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

如何在NestJS Passport-JWT中区分请求拒绝的不同原因?

区分NestJS Passport-JWT认证失败原因的解决方案

核心思路是通过自定义JWT Auth Guard,捕获Passport-JWT抛出的不同类型错误,返回对应明确的错误信息给客户端。

1. 自定义JWT Auth Guard

创建继承自AuthGuard('jwt')的自定义Guard,重写handleRequest方法来识别不同的认证失败场景:

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { TokenExpiredError, JsonWebTokenError } from 'jsonwebtoken';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  handleRequest(err: any, user: any, info: any) {
    // 令牌过期场景
    if (info instanceof TokenExpiredError) {
      throw new UnauthorizedException('令牌已过期');
    }
    // 令牌无效场景(如签名错误、格式非法)
    if (info instanceof JsonWebTokenError) {
      throw new UnauthorizedException('令牌无效');
    }
    // 未提供令牌场景
    if (info?.message === 'No auth token') {
      throw new UnauthorizedException('未提供访问令牌');
    }
    // 其他未覆盖的认证失败场景
    if (err || !user) {
      throw err || new UnauthorizedException('认证失败');
    }
    return user;
  }
}

2. 替换默认Guard使用自定义实现

在需要认证的路由或控制器上,用自定义的JwtAuthGuard替代默认的AuthGuard('jwt'):

import { Controller, Get, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './jwt-auth.guard';

@Controller('api')
export class ProtectedController {
  @Get('protected')
  @UseGuards(JwtAuthGuard)
  getProtectedContent() {
    return { data: '这是受JWT保护的内容' };
  }
}

3. 全局使用自定义Guard(可选)

如果希望所有路由默认启用该认证逻辑,可在根模块中配置全局Guard:

import { APP_GUARD } from '@nestjs/core';
import { JwtAuthGuard } from './jwt-auth.guard';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: JwtAuthGuard,
    },
  ],
})
export class AppModule {}

完成以上配置后,客户端会收到明确的错误响应:

  • 未提供令牌:401 {"message": "未提供访问令牌", "statusCode": 401}
  • 令牌过期:401 {"message": "令牌已过期", "statusCode": 401}
  • 令牌无效:401 {"message": "令牌无效", "statusCode": 401}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:15:35