You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:01:21