NestJS中Refresh Token刷新AccessToken时属性访问undefined问题
问题描述
搭建带有JWT Token和Refresh Token的NestJS API时,调用Refresh Token获取新AccessToken出现异常:refreshToken函数生成AccessToken时Payload为空。打印user对象能看到完整属性值,但访问user.id、user.username等属性均返回undefined。
相关代码
Refresh JWT策略代码
import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { PassportStrategy } from '@nestjs/passport'; import { ExtractJwt, Strategy } from 'passport-jwt'; @Injectable() export class RefreshJwtStrategy extends PassportStrategy( Strategy, 'jwt-refresh', ) { constructor(private readonly configService: ConfigService) { super({ jwtFromRequest: ExtractJwt.fromBodyField('refresh'), ignoreExpiration: false, secretOrKey: configService.get<string>('jwt.refreshSecret'), }); } async validate(payload: any) { return { user: payload.sub, userId: payload.userId }; } }
控制器代码
@UseGuards(RefreshJwtGuard) @Post('/refresh') async refreshToken(@Request() req) { return await this.authService.refreshToken(req.user); }
refreshToken函数代码
async refreshToken(user: User) { console.log(user); // 能正常打印用户对象及属性值 const payload = { userId: user.id, // undefined sub: { id: user.id, // undefined username: user.username, // undefined email: user.email, // undefined }, }; console.log(payload); // 输出为空结构 return { accessToken: this.jwtService.sign(payload), }; }
日志输出
user打印结果
{ user: { id: '8c5370bd-3b5c-404c-8362-fdb6efb84d75', username: 'owner1.1', email: 'owner1.1@gmail.com' }, userId: '8c5370bd-3b5c-404c-8362-fdb6efb84d75' }
payload打印结果
{ userId: undefined, sub: { id: undefined, username: undefined, email: undefined } }
问题原因
从日志可见,req.user的结构是{ user: {...}, userId: ... },但你在refreshToken函数里直接访问user.id,这是结构层级错误——真实的用户属性嵌套在user.user字段下,而非req.user的顶级属性。
根源在RefreshJwtStrategy的validate方法:你返回的对象将用户信息嵌套在user字段中,导致req.user的结构不符合后续代码的访问逻辑。
解决方法
方法一:调整validate方法的返回值
让validate直接返回用户信息,使req.user成为用户对象本身:
async validate(payload: any) { // 直接返回payload.sub中的用户信息 return payload.sub; }
若需保留userId字段,可合并返回:
async validate(payload: any) { return { ...payload.sub, userId: payload.userId }; }
方法二:修正refreshToken函数的属性访问路径
若不想改动策略代码,就在refreshToken中正确访问嵌套的属性:
async refreshToken(user: any) { const payload = { userId: user.userId, sub: { id: user.user.id, username: user.user.username, email: user.user.email, }, }; return { accessToken: this.jwtService.sign(payload), }; }
内容的提问来源于stack exchange,提问作者Yousi
相关产品推荐
相关产品推荐

