NestJS整合JWT+Passport时无法访问validate函数,报401未授权
NestJS JWT认证401问题排查
我正在用NestJS+JWT+Passport实现认证功能,但无论采用何种方式,请求受保护接口都会返回401 Unauthorized错误,甚至无法进入JwtStrategy的validate函数,控制台也没有日志输出。尝试直接使用@nestjs/passport的AuthGuard替代自定义守卫,问题依旧。相关代码如下:
auth.controller.ts
import { Body, Controller, Get, Post, Req, UnauthorizedException, UseGuards } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { LoginDTO } from 'src/user/login.dto'; import { UserService } from 'src/user/user.service'; import { AuthGuard } from './auth.guard'; @Controller() export class AuthController { constructor( private readonly userService: UserService, private readonly jwtService: JwtService ) {} @Post('/signin') async signin(@Body() loginDTO: LoginDTO) { const user = await this.userService.findByLogin(loginDTO); if (!user) { throw new UnauthorizedException('check again'); } const accessToken = this.jwtService.sign({ email: loginDTO.email }); return { accessToken: accessToken }; } @UseGuards(AuthGuard) @Get('/test') async getProfile(@Req() req) { const user = req.user; return user; } }
auth.passport.jwt.ts
import { Injectable, UnauthorizedException } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; import { UserService } from 'src/user/user.service'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { constructor(private userService: UserService) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: true, secretOrKey: `${process.env.AUTH_SECRET_KEY}` }); } async validate(payload: { email: string }) { const { email } = payload; const user = await this.userService.findByEmail(email); if (!user) { throw new UnauthorizedException({ message: 'null' }); } return user; } }
auth.module.ts
import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; import { AuthController } from './auth.controller'; import { UserModule } from 'src/user/user.module'; import { PassportModule } from '@nestjs/passport'; import { JwtStrategy } from './auth.passport.jwt'; @Module({ imports: [ JwtModule.register({ secret: `${process.env.AUTH_SECRET_KEY}` }), UserModule, PassportModule ], controllers: [AuthController], providers: [JwtStrategy] }) export class AuthModule {}
auth.guard.ts
import { ExecutionContext, Injectable } from '@nestjs/common'; import { AuthGuard as NestAuthGuard } from '@nestjs/passport'; @Injectable() export class AuthGuard extends NestAuthGuard('jwt') { canActivate(context: ExecutionContext) { return super.canActivate(context); } }
排查建议
- 检查请求头格式:确保请求
/test接口时,请求头包含Authorization: Bearer <你的accessToken>,注意Bearer和token之间必须有空格。 - 验证密钥一致性:确认
process.env.AUTH_SECRET_KEY在JwtModule和JwtStrategy中是完全相同的值,同时检查环境变量是否正确加载(如果使用@nestjs/config,需确保ConfigModule已全局导入)。 - 添加日志排查流程:在
JwtStrategy的validate函数开头添加console.log('进入validate', payload),在自定义AuthGuard的canActivate里添加console.log('进入AuthGuard'),确认代码是否被触发。 - 校验JWT有效性:用jwt.io解析登录返回的
accessToken,查看payload是否包含正确的email字段,以及签名是否与你的密钥匹配。 - 检查用户查询逻辑:确认
userService.findByEmail能通过token中的email正确查询到用户,可单独测试该方法的返回值。 - 临时关闭过期忽略:将
JwtStrategy中的ignoreExpiration改为false,排除token过期导致的问题(即使你设置了忽略过期,也可临时验证)。
内容的提问来源于stack exchange,提问作者user23483412
相关产品推荐
相关产品推荐

