Nestjs 角色守卫调用 2 次并首先让用户未定义

Nestjs roles guard invokes 2 times and gets user undefined at first

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

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

{
  provide: APP_GUARD,
  useClass: RolesGuard
}

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

由于你如何绑定你的守卫,如前所述,执行看起来像 RolesGuard (global)JwtAuthGuard (route level)RolesGuard (route level)。第二个路由级别守卫,你的第二个 RolesGuardJwtAuthGuard 之后运行 所以它可以像你期望的那样访问 req.user

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