laravel中jwt多用户权限分级需配置独立guard与provider、按guard名精准使用中间件、在中间件中结合guard/权限字段/gate策略实现分级、token黑名单及刷新操作须按guard隔离。

Laravel 中用 JWT 实现多用户权限分级,关键不在“写多少中间件”,而在于守卫(guard)与中间件的配合是否精准。不同用户类型(如 users、admins、merchants)必须走各自独立的 guard,再通过中间件绑定对应权限逻辑,才能避免 token 混用、权限错位或黑名单误删。
一、为每类用户配置独立 Guard 和 Provider
不能只改 jwt.php 里的 user 模型路径——那是全局配置,不支持运行时切换。必须在 config/auth.php 中明确定义多个 guard:
- 添加 admin guard:
'admin' => ['driver' => 'jwt', 'provider' => 'admins'] - 新增 admins provider:
'admins' => ['driver' => 'eloquent', 'model' => App\Models\Admin::class] - 对应模型(Admin)需实现
JWTSubject接口,并在getJWTCustomClaims()中加入'guard' => 'admin'字段,用于后续隔离校验
二、中间件按 Guard 名精准拦截
路由中间件必须显式指定 guard 名,否则默认走 api 或 web,导致鉴权失败或越权:
- 管理员接口加:
->middleware('auth:admin') - 商户接口加:
->middleware('auth:merchant') - 普通用户接口仍用:
->middleware('auth:api') - 注意:不要只写
auth或auth:api就去覆盖所有场景,guard 名必须和 config/auth.php 中定义的一致
三、权限分级靠中间件内嵌逻辑,不依赖单一角色字段
仅判断 $user->role === 'admin' 过于粗糙。更稳妥的做法是在中间件中结合 guard + 权限字段 + Gate 策略:
- 先确认当前 guard 已生效:
Auth::guard('admin')->check() - 再读取用户权限字段(如
$user->permissionsJSON 字符串),或调用Gate::allows('manage_users') - 若需动态权限(如菜单级控制),可在中间件里解析 token payload:
$payload = JWTAuth::getPayload($request),提取自定义声明(如scope、level)做判断
四、Token 管理必须按 Guard 隔离
JWT 默认黑名单是全局共享的,admin 登出可能清掉 user 的 token。解决方法是让缓存 key 或数据库字段带上 guard 标识:
- 重写
JWTBlacklist::add()方法,在 key 前拼上$payload['guard'] . ':' - 刷新 token 时也必须指定 guard:
Auth::guard('admin')->refresh(),不能只调auth()->refresh() - 前端请求头也要保持一致:
Authorization: Bearer xxx对应的 token 必须由auth:admin守卫签发和校验











