JWT多用户差异化鉴权核心是多个guard共存且严格对齐:需在config/auth.php中为admins、merchants等定义独立guard与provider,各模型实现JWTSubject接口,路由中间件明确指定auth:admin等guard名,登录注销均调用对应guard实例,并隔离黑名单与token存储。

JWT多用户差异化鉴权,核心是让不同接口走不同的 guard,各自绑定独立模型、provider 和 token 生命周期逻辑,而不是共用一套认证流程。关键不在改一个配置项,而在于 guard、provider、中间件、路由四者严格对齐。
定义多个 guard 与 provider
在 config/auth.php 中显式声明每个用户类型对应的 guard 和 provider:
- 新增 admin guard:
'admin' => ['driver' => 'jwt', 'provider' => 'admins'] - 新增 merchant guard:
'merchant' => ['driver' => 'jwt', 'provider' => 'merchants'] - 对应新增 providers:
'admins'指向App\Models\Admin::class,'merchants'指向App\Models\Merchant::class - 确保每个模型都实现
JWTSubject接口,并正确返回getJWTIdentifier()和getJWTCustomClaims()
路由与中间件按 guard 隔离
不要靠中间件动态修改 config(如临时改 jwt.user),容易引发并发污染或缓存残留。应直接在路由中指定 guard:
- API 路由分组时明确传入 guard 名:
Route::middleware('auth:admin')->group(...) - 后台接口用
auth:admin,商户接口用auth:merchant,普通用户保持auth:api - 避免混用中间件别名(如只写
auth),必须带冒号后缀以锁定 guard 上下文
登录与 token 管理按 guard 调用
签发、刷新、注销必须使用对应 guard 实例,否则 token 会写错表或触发错误黑名单行为:
- 管理员登录:
Auth::guard('admin')->attempt($credentials),不是Auth::attempt() - 获取当前认证用户:
Auth::guard('merchant')->user(),而非auth()->user() - 登出操作:
Auth::guard('admin')->logout(),确保只清除该 guard 关联的 token
黑名单与 token 存储隔离
tymon/jwt-auth 默认黑名单不区分 guard,需手动适配:
- 重写
Blacklist服务,使其在 key 前缀中加入 guard 名(如blacklist:admin:) - 或改用数据库黑名单表,为每类用户增加
guard字段并查询时带上条件 - 刷新 token 时也要确保
Auth::guard('admin')->refresh(),避免 payload 混淆导致越权


















