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

基于MEAN栈的Passport鉴权401未授权场景处理咨询

解决Token失效后自动清除缓存并跳转登录页的问题

看来你遇到了JWT令牌失效后,前端只在控制台打印"Unauthorized"但没自动处理跳转的问题。其实这个需求需要后端+前端配合来实现,我帮你一步步梳理:

第一步:先让后端返回明确的401错误状态码

你的passport.js里已经配置了JWT策略,但现在鉴权失败时,Passport默认的响应可能没有明确返回401状态码,导致前端没法准确判断。咱们需要做两处调整:

1. 给受保护路由添加鉴权中间件

在你的各个路由文件(比如users.js、customer.js)里,所有需要登录才能访问的接口,都要加上passport.authenticate('jwt', {session: false})中间件,并且处理鉴权失败的情况:

// 举个例子:用户信息接口
router.get('/profile', 
  passport.authenticate('jwt', {session: false}), 
  (req, res) => {
    // 正常返回用户数据
    res.json({user: req.user});
  }, 
  (err, req, res, next) => {
    // 捕获Passport的未授权错误
    if (err.name === 'UnauthorizedError') {
      res.status(401).json({success: false, message: 'Token已失效,请重新登录'});
    }
  }
);

2. 全局错误处理(可选但推荐)

如果不想每个路由都写错误处理,你可以在app.js里加一个全局错误中间件,统一处理所有鉴权失败的情况:

// 放在所有路由注册之后
app.use((err, req, res, next) => {
  if (err.name === 'UnauthorizedError') {
    res.status(401).json({success: false, message: 'Token失效或未授权'});
  } else {
    // 其他错误交给默认处理
    next(err);
  }
});

这样后端在Token失效或无效时,就会明确返回401状态码,前端就能准确捕获这个错误了。

第二步:前端用HTTP拦截器处理401错误(Angular端)

因为是MEAN栈,前端是Angular,咱们可以创建一个HTTP拦截器,拦截所有接口响应,一旦检测到401,就执行清除localStorage和跳转登录页的逻辑。

1. 创建鉴权拦截器

新建一个auth.interceptor.ts文件:

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Router } from '@angular/router';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  constructor(private router: Router) {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      catchError((error: HttpErrorResponse) => {
        // 检测到401未授权状态码
        if (error.status === 401) {
          // 清除localStorage里的Token和用户信息
          localStorage.removeItem('token');
          localStorage.removeItem('user');
          // 跳转到登录页面
          this.router.navigate(['/login']);
        }
        // 把错误继续抛出,方便其他组件处理(可选)
        return throwError(() => new Error(error.message || '服务器异常'));
      })
    );
  }
}

2. 注册拦截器

在app.module.ts里把这个拦截器注册到Angular的HTTP服务中:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, AppRoutingModule, HttpClientModule],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true // 允许多个拦截器
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

额外提醒(如果是AngularJS老版本)

要是你的前端用的是AngularJS(1.x版本),拦截器写法不一样,用$httpProvider来注册:

angular.module('yourApp')
.factory('authInterceptor', function($q, $location, $window) {
  return {
    responseError: function(rejection) {
      if (rejection.status === 401) {
        $window.localStorage.removeItem('token');
        $location.path('/login');
      }
      return $q.reject(rejection);
    }
  };
});

// 在配置阶段添加拦截器
angular.module('yourApp')
.config(function($httpProvider) {
  $httpProvider.interceptors.push('authInterceptor');
});

最后别忘了,前端发送请求时要把Token放在请求头里,比如Authorization: jwt <你的token>,这样后端Passport才能正确提取验证。

这样设置后,下次Token失效时,用户点击任何需要鉴权的链接,前端都会自动清除缓存并跳转到登录页,而不是只在控制台打印提示啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:24:57