我使用NestJS作为客户端API的框架。在框架内,我们正在使用一个非常标准的Passport / JWT auth基础设施,该工作正常。我们的AuthGuard在找到承载令牌时触发,在安全的API端点中,我可以通过' @Res()请求注入HTTP上下文。并访问" request.user'包含我的Jwt令牌的有效负载的属性。
除此之外,我们正在尝试实施一个' RolesGuard'与文档中提供的示例代码以及GitHub上的一些示例项目非常相似(没有一个实际使用此防护,但它们将其作为示例防护包括在内)。
我们的问题是我们的AuthGuard会触发并验证Jwt令牌,然后我们的RolesGuard会触发,但传递的请求对象没有附加到请求的用户元数据。
我们的RolesGuard中的关键代码是:
const request = context.switchToHttp().getRequest();
const user = request.user;
if (!user) {
return false;
}
在上面的剪辑中,用户总是假的。有没有人在Nest中编写了一个基于角色/权限的保护,成功访问了当前用户的范围?所有代码都被触发,所有内容都显示正确。
-Kevin
答案 0 :(得分:7)
最终这似乎是警卫的订购问题,并且它看起来不容易解决(没有框架允许对订购进行一些控制)。
我希望全球注册RolesGuard,但这会导致首先注册并首先开火。
@UseGuards(AuthGuard('jwt'), RolesGuard)
@Roles('admin')
如果我在端点级别注册它并将其放在AuthGuard之后然后它会触发第二个并且我获得了我期望在防护本身内的用户上下文。它并不完美,但它有效。
-Kevin
答案 1 :(得分:1)
如果其他人偶然发现了这个问题:将多个守卫放入一个 @UseGuards
装饰器是可行的,但是如果您想将它们分开(例如,如果您使用自定义装饰器),您可以授予第二个守卫访问权限req.user
通过将它放在之前将用户置于请求对象上的@UseGuards
调用,如下例所示:
@RestrictTo(UserAuthorities.admin)
@UseGuards(JwtAuthGuard)
@Get("/your-route")
这似乎是 how decorators work in TypeScript 的结果。
答案 2 :(得分:0)
在端点级别注册RoleGuard并将其放在AuthGuard之后,然后第二次触发,我得到了在guard自身内期望的用户上下文。 不要在模块上注册RoleGuard,因为它将首先注册并首先触发。
*。module.ts
imports: [],
providers: [{provide: APP_GUARD, useClass: RolesGuard} ,], // remove guard
controllers: [],
exports: [],