NestJs + MongoDB自定义CurrentUser装饰器获取用户异常求助
问题分析与解决方案
你的问题核心是JWT验证后request.user被错误设置为数据库第一个用户,而非当前登录用户,和CurrentUser装饰器本身无关(你的装饰器代码是正确的)。以下是排查和解决步骤:
1. 检查JWT策略的validate方法(最可能的原因)
Passport的JWT策略中,validate方法返回的用户对象会被自动挂载到request.user上。如果你的validate方法没有根据JWT payload中的用户唯一标识查询,而是直接调用findOne()不带条件,就会返回数据库第一个用户。
错误示例:
async validate(payload: any) { // 无查询条件,返回数据库第一个用户 return this.userService.findOne(); }
正确写法:
确保根据JWT payload里的用户ID(通常存在sub字段)查询对应用户:
@Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor(private userService: UserService) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: process.env.JWT_SECRET, }); } async validate(payload: any) { // 根据payload中的用户ID查询 const user = await this.userService.findOne({ _id: payload.sub }); if (!user) throw new UnauthorizedException(); return user; // 正确返回当前登录用户 } }
2. 排查自定义@Auth()装饰器
你的控制器同时使用了@UseGuards(AuthGuard('jwt'))和@Auth(),如果@Auth()是自定义守卫/装饰器,可能内部逻辑错误地覆盖了request.user,比如重复查询用户且未带正确条件。
- 检查
@Auth()的实现,移除任何不必要的用户查询逻辑,避免和AuthGuard('jwt')的逻辑冲突。 - 如果
@Auth()只是用于权限控制,确保它不会修改request.user的值。
3. 验证请求流程中的request.user
在控制器方法中打印完整的request对象,确认request.user在进入方法前是否已被正确设置:
async toggleFriend( @CurrentUser() user: UserModel, @Req() request: Request ) { console.log('完整request.user:', request.user); console.log('CurrentUser装饰器获取:', user); }
如果request.user本身就是错误的,说明问题出在AuthGuard或后续中间件,而非装饰器。
内容的提问来源于stack exchange,提问作者MarkSakhar
相关产品推荐
相关产品推荐

