laravel jwt 支持多用户类型需配置独立 guard、provider、模型及中间件:1. auth.php 中为 admins/merchants 定义专属 jwt guard 和 eloquent provider;2. 各模型实现 jwtsubject 并返回含 guard 标识的自定义 claims;3. 登录鉴权必须显式调用 auth::guard('xxx');4. 路由中间件严格匹配 guard 名如 auth:admin。

要让 Laravel 的 JWT 支持多用户类型(比如 users、admins、merchants),关键不是改一个配置就完事,而是为每类用户建立独立的 guard,并确保它和 provider、model、中间件、登录逻辑完全对齐。
1. 在 auth.php 中定义多个 JWT guard
每个 guard 必须明确指定 driver 为 jwt,并绑定专属 provider:
- 在
config/auth.php的'guards'数组里新增:
'admin' => [
'driver' => 'jwt',
'provider' => 'admins',
],
'merchant' => [
'driver' => 'jwt',
'provider' => 'merchants',
],
- 对应在
'providers'中添加匹配项:
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
'merchants' => [
'driver' => 'eloquent',
'model' => App\Models\Merchant::class,
],
guard 名(如 admin)和 provider 名(如 admins)必须一一对应,不能拼错或混用。
2. 每个用户模型实现 JWTSubject 接口
不只是 User 模型,Admin、Merchant 等也得实现接口并返回唯一标识:
- 在模型中 use
Tymon\JWTAuth\Contracts\JWTSubject -
getJWTIdentifier()返回主键(如$this->id) -
getJWTCustomClaims()至少加入 guard 标识,例如:return ['guard' => 'admin'];
这个字段后续用于黑名单隔离和 payload 区分,不能省略。
3. 登录与鉴权必须显式指定 guard
所有操作都不能依赖默认 guard,否则会走错表或拿错用户:
- 登录时用
Auth::guard('admin')->attempt($credentials),而不是Auth::attempt() - 生成 token 用
Auth::guard('admin')->login($admin) - 获取当前用户用
Auth::guard('admin')->user() - 登出用
Auth::guard('admin')->logout()
漏掉 ->guard('xxx') 就等于没配多守卫——系统会退回到默认 guard(通常是 web 或 api),导致查 users 表、返回 User 实例,即使你请求的是管理员接口。
4. 中间件与路由严格匹配 guard 名
保护路由时,中间件名必须带 guard 参数:
- 正确写法:
middleware('auth:admin')或middleware('auth:merchant') - 错误写法:
middleware('auth:api')(除非你把 api guard 配成了 merchant) - 刷新 token 接口也要指定 guard:
Auth::guard('admin')->refresh()
如果用了 auth:admin,merchant 这种多参数写法,Laravel 会按顺序尝试,只要一个通过即放行,但不建议混用——容易掩盖权限边界问题。











