Jwt 策略后 ExecutionContext 中缺少用户

User missing in ExecutionContext after Jwt strategy

目前我已经实现了 jwt guard,它工作得很好,使用 Passport,jwt 正在验证颁发的令牌,我可以通过 @Request 通过 req.user 来查看用户,在实现基于角色的身份验证后出现问题作为已经工作的 jwt 守卫的插件。

我遵循了 nestjs.com 提供的指导,但没有帮助。 https://docs.nestjs.com/guards

基本角色配置:

roles.decorator.ts

import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);

roles.guard.ts

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    console.log(user);
    const hasRole = () => user.roles.some((role) => roles.includes(role));
    return user && user.roles && hasRole();
  }
}

RolesGuard 通过以下方式注入 app.module.ts 内容:

providers: [{
    provide: APP_GUARD,
    useClass: RolesGuard,
  }]

我的控制器header验证:

  @UseGuards(AuthGuard('jwt'))
  @Roles('admin')
  @Get('admin')
  async admin(@Request() req) {
    return this.authService.me(req.user);
  }

它应该检查用户是否提供了 Bearer 令牌并且它是活动的,jwt 也会将用户分配给请求用户,我可以使用 @Request() req 然后 req.user 检索它,但是当涉及到@Roles('admin'),它 returns undefinedroles.guard.ts 在 "console.log(user)" 部分最后,不允许用户看到给定的资源,似乎 RoleGuardAuthGuard('jwt') 之前被注入,但是请求内部有 Brearer 令牌,所以它应该被转换给用户。

我正在考虑更改我的 jwt 策略并在那里实现 CanActivate 接口并将其写入那里,但这对我来说听起来不是一个好的解决方案,因为我想将它们分开。

我可以为您确认 RoleGuardAuthGuard 之前被调用,因为 RoleGuard 是全局范围内的应用程序(在您定义的位置)和AuthGuard 是函数的局部范围。如果您不介意 RoleGuard 没有全局作用域而是针对每个方法作用域,即使需要编写更多代码,您也可以将其添加到 @UseGuards 装饰器。除此之外,就像你说的,你可以将两个守卫合二为一,但这可能会变得混乱和笨重。