Guard 说用户在 NestJS 中未定义

Guard says user is undefined in NestJS

@UseGuards(JwtAccessTokenAuthGuard)
@ApiBearerAuth()
@SetMetadata('roles', Role.ADMIN)
@UseGuards(RolesGuard)
@Post('/add/card')
addCard(@Body() addCardDto: AddCardDto) {
  return this.storeService.addCard(addCardDto);
}

这是 RoleGuard

canActivate(context: ExecutionContext): boolean {
  const roles = this.reflector.get<string[]>('roles', context.getHandler());
  if (!roles) {
    return true;
  }
  const user = context.switchToHttp().getRequest().user;
  return this.matchRoles(roles, user.user_type);
}

在此,请求对象在正文或函数内部有用户 addCard 但在 RoleGuard 中没有。他们说未定义。为什么这样?在 JwtAccessTokenGuard 我返回了用户 属性.

我想在 Guard 内部检查它,而不是在运行中。我做错了什么。

为了让用户通过这个方法进入守卫:

const user = context.switchToHttp().getRequest().user;

您应该return 本地策略中的用户对象。将 user 对象附加到 request 对象。主体与 user 对象无关。所以,你的 local.strategy.ts 应该是这样的:

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super({ usernameField: 'email' });
  }

  async validate(email: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(email, password);

    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

有关详细信息,请参阅 here

当使用两个相同的装饰器时,我记得顺序是代码中最低的装饰器在前,然后是最高的装饰器。在这种情况下,为什么不将两个 @UseGuards() 合并为一个像 @UseGuards(JwtAccessTokenAuthGuard, RolesGuard) 这样的装饰器,这样你就可以确定 运行 在 as described in the docs 中守卫的顺序