Nestjs处理Internal server error:无token时正确抛出UnauthorizedException
问题根源
你代码中的问题主要有两点:
try...catch捕获了所有内部抛出的异常,包括你主动抛出的UnauthorizedException,捕获后直接返回false,没有把异常向外传递给Nest的异常处理层,自然无法返回预期的401响应- 没有对
request.headers.authorization做非空判断,如果请求压根没有携带这个头,直接调用.split(' ')会抛出类型错误,同样会被catch吞掉,最终返回不符合预期的500或者403错误
调整后代码
import { Injectable, CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; @Injectable() export class JwtAuthGuard implements CanActivate { constructor(private jwtService: JwtService) {} canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); const authHeader = request.headers.authorization; // 提前校验请求头是否符合Bearer Token格式 if (!authHeader || !authHeader.startsWith('Bearer ')) { throw new UnauthorizedException('Token is not provided.'); } const jwt = authHeader.split(' ')[1]; if (!jwt) { throw new UnauthorizedException('Token is not provided.'); } try { const payload = this.jwtService.verify(jwt); // 校验通过后将用户信息挂载到请求对象上,方便后续业务逻辑使用 request.user = payload; return true; } catch (e) { // 令牌校验失败统一抛出401 throw new UnauthorizedException('Invalid token.'); } } }
调整说明
- 提前对Authorization请求头做非空、前缀校验,避免空指针异常
- 将令牌提取逻辑移出try块,主动抛出的未携带令牌异常不会被捕获,会直接交给Nest的异常处理层返回401响应
- 仅对JWT校验逻辑包裹try...catch,校验失败直接抛出对应401异常,不会吞掉错误
- 校验通过后将用户载荷挂载到request对象上,后续接口可以直接读取
request.user获取当前登录用户信息
内容的提问来源于stack exchange,提问作者user16907356
相关产品推荐
相关产品推荐

