Javascript NestJs-无法在RolesGuard中获取用户上下文

Javascript NestJs-无法在RolesGuard中获取用户上下文,javascript,nestjs,Javascript,Nestjs,我使用NestJS作为客户端API的框架。在这个框架内,我们使用了一个非常标准的Passport/JWT auth基础设施,它工作得很好。当找到承载令牌时,我们的AuthGuard将启动,在安全API端点中,我可以通过“@Res()request”注入HTTP上下文,并访问包含Jwt令牌负载的“request.user”属性 除此之外,我们还试图以与文档中提供的示例代码和GitHub上的一些示例项目非常相似的方式实现“RolesGuard”(没有一个项目实际使用此guard,但它们将其作为示例g

我使用NestJS作为客户端API的框架。在这个框架内,我们使用了一个非常标准的Passport/JWT auth基础设施,它工作得很好。当找到承载令牌时,我们的AuthGuard将启动,在安全API端点中,我可以通过“@Res()request”注入HTTP上下文,并访问包含Jwt令牌负载的“request.user”属性

除此之外,我们还试图以与文档中提供的示例代码和GitHub上的一些示例项目非常相似的方式实现“RolesGuard”(没有一个项目实际使用此guard,但它们将其作为示例guard)

我们的问题是AuthGuard激发并验证Jwt令牌,然后RolesGuard激发,但它传递的请求对象没有附加到请求的用户元数据

RolesGuard中的关键代码是:

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

    if (!user) {
        return false;
    }
在上面的截图中,用户总是错误的。是否有人在Nest中编写了基于角色/权限的guard,成功访问当前用户的范围?所有代码都已启动,所有内容都已正确注册


-凯文

最终,这似乎是一个与警卫有关的订购问题,看起来不容易解决(没有框架允许对订购进行某种控制)

我的希望是在全球范围内注册RolesGuard,但这会导致它先注册,先开火

@UseGuards(AuthGuard('jwt'), RolesGuard)
@Roles('admin')
如果我在端点级别注册它,并将它放在AuthGuard之后,那么它会触发第二个命令,并且我会得到我期望的guard本身中的用户上下文。它不是完美的,但很管用


-Kevin

在端点级别注册RoleGuard并将其放在AuthGuard之后,然后它第二次触发,我得到了guard本身所期望的用户上下文。 不要在模块上注册RoleGuard,因为它会先注册,然后再开火

@UseGuards(AuthGuard('jwt'), RolesGuard)
@Roles('admin')
*.module.ts

imports: [],
  providers: [{provide: APP_GUARD, useClass: RolesGuard} ,],  // remove guard
  controllers: [],
  exports: [],

如果其他人偶然发现了这个问题:将多个卫士放在一个
@UseGuards
装饰器中是可行的,但是如果你想将它们分开(比如说,如果你使用自定义装饰器),您可以将第二个guard访问权授予
req.user
,方法是将其置于将用户置于请求对象上的
@UseGuards
调用之前,如本例所示:

@RestrictTo(UserAuthorities.admin)
@UseGuards(JwtAuthGuard)
@Get("/your-route")

这似乎是一个结果。

这应该被标记为答案。它工作得很好,可以显式地命令守卫。它可以通过中间件和方法的元数据来解决,但我不想麻烦…这可以通过使用express会话来解决吗?或者这不是一个好方法?我发现这个答案完全可以接受,应该可以解决99%的用例。我假设您试图将此逻辑实现为全局保护,它将在JWT auth保护之前执行(假设它在控制器或路由级别注册)。查看请求生命周期。顺序:全局守卫->控制器守卫->路由守卫