我使用护照,想按角色保护少数路线。看起来警卫调用了 2 次。起初它记录用户未定义。第二次它记录用户正确。我做错了什么?查看实现的屏幕截图。
1 回答
守卫第一次运行来自全局绑定守卫
{
provide: APP_GUARD,
useClass: RolesGuard
}
由于这是一个全局守卫,它将是请求链中调用的第一个守卫(并且因为没有其他守卫)。您RolesGuard
正在查看req.user
由 分配的属性passport
。在 NestJS 中,这通常由AuthGuard
which 将在后台调用来完成passport.authenticate()
。那里的代码有点复杂,所以现在相信我。
由于你如何约束你的守卫,如前所述,执行看起来像RolesGuard (global)
, JwtAuthGuard (route level)
, RolesGuard (route level)
. 第二个路线级别的守卫,你的第二个在之后RolesGuard
运行,所以它可以访问你所期望的。JwtAuthGuard
req.user
现在,您可能会问的下一个问题是“我该如何解决这个问题?” 我过去为此所做的是绑定了我的JwtAuthGuard
(或类似的)全局并在RolesGuard
. 使用装饰器,我们可以将元数据添加到类和路由处理程序中(就像 Nest 一开始就能够做到的那样)并通过ExecutionContext
incanActivate
方法从守卫中读取它。您也可以将 NestReflector
注入警卫类并进行检查,例如this.reflector.getAllAndMerge<boolean>('SHOULD_SKIP_AUTH', [context.getHandler(), context.getClass()])
. 从理论上讲,这将返回一个您通过类或路由处理程序级别的装饰器设置的布尔值,如果它返回true
(即您应该跳过身份验证),那么请求保护可能会短路到return true
并让请求自行移动。