Nestjs 角色防护调用 2 次并首先获取用户未定义

lys*_*vlc 1 node.js nestjs nestjs-passport

我使用护照并希望按角色保护几条路线。看起来守卫调用了两次。首先它记录用户未定义。第二次它记录用户正确。我做错了什么?请参阅实施截图。

角色守卫

应用程序模块

用法

Jay*_*iel 10

守卫第一次运行来自于全局绑定的守卫

{
  provide: APP_GUARD,
  useClass: RolesGuard
}
Run Code Online (Sandbox Code Playgroud)

由于这是一个全局守卫,因此它将是请求链中调用的第一个守卫(并且因为没有其他守卫)。您RolesGuard正在查看req.user由 分配的属性passport。在 NestJS 中,这通常是通过在后台AuthGuard调用来完成的。passport.authenticate()那里的代码有点复杂,所以现在相信我。

正如前面提到的,由于你如何束缚你的守卫,执行看起来像RolesGuard (global), JwtAuthGuard (route level), RolesGuard (route level)。第二个路线级别的守卫,你的第二个在后面RolesGuard运行,所以它可以像你期望的那样访问。JwtAuthGuardreq.user

现在,您可能会问的下一个问题是“我该如何解决这个问题?” 我过去为此所做的是绑定我的JwtAuthGuard(或类似的)全局并在 之前运行它RolesGuard,但添加了元数据检查以判断路由是否应受授权保护。使用装饰器,我们可以将元数据添加到类和路由处理程序中(这就是 Nest 最初能够做的事情),并通过 inExecutionContext方法从守卫中读取它canActivate。您也可以将 Nest 注入Reflector到防护类中并进行类似的检查this.reflector.getAllAndMerge<boolean>('SHOULD_SKIP_AUTH', [context.getHandler(), context.getClass()])。理论上,这将返回一个您通过类或路由处理程序级别的装饰器设置的布尔值,如果它返回true(即您应该跳过身份验证),则请求防护可以短路到 areturn true并让请求在其上移动自己的。