You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel JWT令牌刷新异常:需实现所有token错误跳转登录页

解决方案:统一Token错误处理实现自动跳转登录页

核心思路

让后端所有Token相关错误统一返回401状态码,配合前端拦截器捕获401后执行登出跳转逻辑,即可实现所有Token异常场景下的统一处理。


1. 修改Laravel JWT中间件

调整中间件代码,确保所有Token异常(包括黑名单、无法刷新、无效、过期、缺失)都返回401状态码,同时保留具体错误信息方便前端提示:

public function handle($request, Closure $next)
{
    try {
        $user = JWTAuth::parseToken()->authenticate();
    } catch (Exception $e) {
        // 令牌无效
        if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException) {
            return response()->json([
                'error' => 'Token is Invalid'
            ], 401);
        } 
        // 令牌过期尝试刷新
        else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException) {
            try {
                $refreshed = JWTAuth::refresh(JWTAuth::getToken());
                $user = JWTAuth::setToken($refreshed)->toUser();
                $request->headers->set('Authorization','Bearer '.$refreshed);
            } catch (\Tymon\JWTAuth\Exceptions\JWTException $e) {
                // 捕获刷新失败的所有场景:黑名单/无法刷新
                $errorMsg = $e instanceof \Tymon\JWTAuth\Exceptions\TokenBlacklistedException 
                    ? 'The token has been blacklisted' 
                    : 'Token has expired and can no longer be refreshed';
                
                return response()->json([
                    'error' => $errorMsg
                ], 401);
            }
        } 
        // 请求无令牌
        else {
            return response()->json([
                'error' => 'Authorization Token not found'
            ], 401);
        }
    }
    return $next($request);
}

2. 优化前端拦截器

在现有拦截器基础上,增加错误信息的动态提示,并避免重复跳转登录页:

export class AuthInterceptor implements HttpInterceptor {
    constructor(
        private tokenService: TokenService,
        private _router: Router,
        private auth: AuthStateService, 
        private toastr: ToastrService
    ) { }

    intercept(req: HttpRequest<any>, next: HttpHandler) {
        const accessToken = this.tokenService.getToken();
        req = req.clone({
            setHeaders: {
                Authorization: "Bearer " + accessToken
            }
        });

        return next.handle(req).pipe(
            catchError((err, caught) => {
                if (err.status === 401){
                    // 提取后端返回的具体错误信息,默认显示通用提示
                    const errorMsg = err.error?.error || 'Unauthorised Access';
                    this.handleAuthError(errorMsg);
                    return of(err);
                }
                throw err;
            })
        );
    }

    private handleAuthError(errorMsg: string) { 
        this.toastr.error(errorMsg, 'Warning');
        this.auth.setAuthState(false);
        this.tokenService.removeToken();
        // 避免当前已在登录页时重复跳转
        if (this._router.url !== '/login') {
            this._router.navigate(['/login']);
        }
    }
}

实现效果

无论出现以下哪种Token错误,前端都会自动清除本地Token、更新登录状态并跳转到登录页:

  • Token已被列入黑名单
  • Token过期且无法刷新
  • Token无效
  • 请求未携带Token

内容的提问来源于stack exchange,提问作者user3653474

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:20:27