NestJS使用accessToken访问validate-code路由返回Unauthorized问题
问题分析与解决:NestJS JWT授权返回401错误
核心错误点
- 守卫类型错配:
validate-code路由使用了LocalAuthGuard,但该守卫是用于用户名密码式的本地登录验证,而非JWT Bearer令牌验证,你需要替换为JwtAuthGuard。 - JwtStrategy依赖导入错误:当前
JwtStrategy中导入的Strategy来自passport-local,但JWT策略必须使用passport-jwt包中的Strategy,这会直接导致JWT验证逻辑失效。 - 异常类拼写错误:
LocalStrategy中使用的UnauthroziedException是拼写错误,正确类名为UnauthorizedException,拼写错误会导致异常抛出逻辑异常。 - LocalStrategy字段配置缺失:passport-local默认使用
username和password作为验证字段,但你的逻辑使用mobileNumber,需在super()中显式配置字段映射。
修正后的关键代码
1. 修复JwtStrategy的依赖导入
import { PassportStrategy } from "@nestjs/passport"; import { ExtractJwt, Strategy } from "passport-jwt"; // 从passport-jwt导入正确的Strategy export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { constructor() { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: `${process.env.JWT_SECRET}`, ignoreExpiration: false, passReqToCallback: true, }); } async validate(payload: any) { return { mobileNumber: payload.mobileNumber }; } }
2. 替换validate-code路由的守卫
@UseGuards(JwtAuthGuard) // 替换为JWT守卫 @Post('validate-code') async validateCode(@Body() dto:VerifyCodeDto,@Res() res:Response):Promise<Response<any,Record<string, any>>>{ const [statusCode,data] = await this.authService.verifyCode(dto); return res.status(statusCode).json(data); }
3. 修复LocalStrategy的拼写与配置
import { Injectable, UnauthorizedException } from "@nestjs/common"; // 修正异常类拼写 import { PassportStrategy } from "@nestjs/passport"; import { Strategy } from 'passport-local'; import { SignupService } from "./signup.service"; @Injectable() export class LocalStrategy extends PassportStrategy(Strategy) { constructor(private readonly signupService: SignupService) { // 配置验证字段为mobileNumber super({ usernameField: 'mobileNumber' }); } async validate(mobileNumber: string) { const user = await this.signupService.validateUser(mobileNumber); if (!user) { throw new UnauthorizedException(); // 修正异常类拼写 } return user; } }
额外检查项
- 确保运行时
process.env.JWT_SECRET已正确加载,JWT签名和验证使用的是同一密钥。 - 检查accessToken是否过期(当前配置为
expiresIn: '60s',测试时需确保令牌未过期)。 - Postman中Bearer Token格式需正确:
Bearer <你的令牌内容>,注意Bearer与令牌之间的空格。
内容的提问来源于stack exchange,提问作者DolDurma
相关产品推荐
相关产品推荐

