0

我使用护照,想按角色保护少数路线。看起来警卫调用了 2 次。起初它记录用户未定义。第二次它记录用户正确。我做错了什么?查看实现的屏幕截图。

角色守卫

应用模块

用法

4

1 回答 1

7

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

{
  provide: APP_GUARD,
  useClass: RolesGuard
}

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

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

现在,您可能会问的下一个问题是“我该如何解决这个问题?” 我过去为此所做的是绑定了我的JwtAuthGuard(或类似的)全局并在RolesGuard. 使用装饰器,我们可以将元数据添加到类和路由处理程序中(就像 Nest 一开始就能够做到的那样)并通过ExecutionContextincanActivate方法从守卫中读取它。您也可以将 NestReflector注入警卫类并进行检查,例如this.reflector.getAllAndMerge<boolean>('SHOULD_SKIP_AUTH', [context.getHandler(), context.getClass()]). 从理论上讲,这将返回一个您通过类或路由处理程序级别的装饰器设置的布尔值,如果它返回true(即您应该跳过身份验证),那么请求保护可能会短路到return true并让请求自行移动。

于 2021-01-13T16:28:13.267 回答