laravel jwt多用户鉴权需为users、admins、merchants分别配置独立guard、provider及token逻辑,并通过中间件显式指定守卫名,确保token隔离与校验精准匹配,防止越权和误删。

要实现 Laravel 中 JWT 多用户(如 users、admins、merchants)的中间件鉴权,关键不是“改一个配置”,而是让每个用户类型拥有独立的 guard、provider、token 生成与校验逻辑,并通过中间件精准绑定对应守卫。否则容易出现 token 越权(比如管理员 token 访问用户接口)或 logout 误删他人 token 等安全问题。
一、定义多守卫与多提供者
在 config/auth.php 中新增 guard 和 provider,确保一一对应:
-
添加 admin guard:
'admin' => ['driver' => 'jwt', 'provider' => 'admins'] -
添加 admins provider:
'admins' => ['driver' => 'eloquent', 'model' => App\Models\Admin::class] - 同理为 merchant 添加
'merchant'guard 和'merchants'provider - 每个模型(Admin、Merchant)必须实现
JWTSubject接口,并在getJWTCustomClaims()中写入守卫标识,例如:return ['guard' => 'admin'];
二、中间件需显式指定守卫名
路由中不能只写 middleware('auth:api'),而要带上具体守卫名:
Route::get('/admin/dashboard', [AdminController::class, 'index'])->middleware('auth:admin');Route::get('/merchant/orders', [MerchantController::class, 'list'])->middleware('auth:merchant');- 中间件内部会调用
Auth::guard('admin')->user(),而非默认 guard,避免取错模型
三、Token 隔离必须落地到存储层
JWT 默认黑名单/缓存不区分 guard,必须手动切片:
- 重写
JWTBlacklist::add()方法,在 cache key 或数据库字段中加入$payload['guard']前缀,例如:blacklist:admin:xxx - 刷新 token 时也必须显式调用:
Auth::guard('admin')->refresh(),否则走默认 guard 可能混用 payload - 登录时务必用守卫实例:
Auth::guard('admin')->login($admin),而不是Auth::login($admin)
四、请求头与路由分组保持一致
前端请求必须携带正确的 guard 上下文:
- 管理端请求头:
Authorization: Bearer xxx,且该 token 是由adminguard 签发的 - 不要混用:移动端 token(
guard=users)不能用于访问auth:admin路由,中间件会因 payload 中guard !== 'admin'直接拒绝 - 可配合自定义中间件做守卫校验增强,例如检查 payload 是否含
guard字段且值匹配当前路由守卫名











