Laravel 多守卫 JWT 刷新需为每个守卫(如 api、admin)独立管理令牌生命周期,刷新时显式指定 guard 参数并校验 token 中 guard 声明,隔离存储 refresh token(加 guard 字段或缓存 key 分区),禁用跨守卫混用。

在 Laravel 中实现多守卫(multi-guard)JWT 刷新令牌,核心在于:每个守卫(如 api、admin、seller)需独立管理自己的 JWT 令牌生命周期,刷新时不能跨守卫混用,且需明确指定目标守卫上下文。
守卫配置与 JWT 实例分离
确保每个守卫在 config/auth.php 中定义清晰,并为每个守卫配置独立的 JWT provider(如 tymon/jwt-auth 或 laravel/sanctum 替代方案)。若使用 tymon/jwt-auth(v1.x),它原生不支持多守卫自动切换,需手动绑定对应 guard 的 JWTAuth 实例:
- 在控制器构造函数或方法中,通过
Auth::guard('admin')获取指定守卫实例 - 使用
JWTAuth::setToken(...)->setSubject(...)手动设置 token 上下文,避免默认守卫干扰 - 推荐为每个守卫注册独立的 JWT service(如
AdminJWTManager),封装 token 生成、验证、刷新逻辑
刷新接口需显式声明守卫
刷新请求必须携带守卫标识(如 URL 参数 ?guard=admin 或请求头 X-Guard: admin),不可依赖 session 或中间件自动推断。示例控制器方法:
- 接收
Authorization: Bearer {refresh_token}头 - 解析 token 后,读取其 payload 中的
guard声明(建议在签发时写入,如'guard' => 'admin') - 校验该 token 是否属于对应守卫的 refresh token 黑名单(可复用
JWTBlacklist,但按guard:token_id分区存储) - 成功后,为同一守卫签发新的 access token 和 refresh token
刷新令牌的安全隔离
不同守卫的 refresh token 必须物理隔离:
- 数据库中 refresh token 表增加
guard字段,查询时强制 WHERE 条件 - 缓存 key 设计为
jwt:refresh:{guard}:{hash},避免 key 冲突 - 禁止将一个守卫的 refresh token 用于另一个守卫的
auth:api中间件校验——中间件应动态传入 guard 名
控制器示例片段(Laravel + tymon/jwt-auth)
以下为精简逻辑,不含异常处理:
public function refresh(Request $request)
{
$guard = $request->input('guard', 'api');
$token = $request->bearerToken();
<pre class="brush:php;toolbar:false;">// 手动切换 JWT 实例
$jwt = app('tymon.jwt.auth');
$jwt->setConfig(app('tymon.jwt.config')->setGuard($guard));
try {
$payload = $jwt->parseToken()->getPayload();
if ($payload['guard'] !== $guard) {
throw new UnauthorizedHttpException('Invalid guard in token');
}
$newToken = $jwt->refresh();
return response()->json([
'access_token' => $newToken,
'token_type' => 'bearer',
'expires_in' => auth($guard)->factory()->getTTL() * 60
]);
} catch (TokenInvalidException $e) {
// 处理过期/篡改
}}











