Laravel 8 自定义角色中间件无法按用户角色保护路由问题排查
故障根因
你的中间件判断逻辑存在两处核心错误:
- 你在已经获取到的当前登录用户实例上调用
role()本地作用域,会发起一个新的全局用户表查询,不会限定当前用户的ID,返回的是所有符合指定角色的用户集合 - 你用
get()获取结果后直接取反判断:PHP中所有对象(包括空的Laravel集合)转布尔值都是true,所以!$collection的结果永远为false,权限校验的判断条件永远不会触发,自然所有用户都能访问路由
修复方案
你不需要额外查询数据库,当前登录用户的role字段已经随登录态加载,直接判断属性即可,修改中间件handle方法代码如下:
public function handle(Request $request, Closure $next, $role) { // 已加auth中间件可省略$request->user()存在判断,加了更稳妥 if (is_null($request->user()) || $request->user()->role !== $role) { return back(); } return $next($request); }
如果你要保留role作用域的写法,也可以修改判断逻辑为校验当前用户是否符合条件,不过属于冗余查询,不推荐:
// 不推荐的冗余写法,仅做逻辑参考 if (!$request->user()->role($role)->where('id', $request->user()->id)->exists()) { return back(); }
内容的提问来源于stack exchange,提问作者Diego Utreras
相关产品推荐
相关产品推荐

