目前我已经实现了 jwt 防护,它工作得很好,使用 Passport,jwt 正在验证颁发的令牌,我可以通过 @Request 通过 req.user 查看用户,在实现基于角色的身份验证作为已经工作的附加组件后出现问题JWT 的守卫。
我遵循了 Nestjs.com 提供的指导,但没有帮助。 https://docs.nestjs.com/guards
基本角色配置:
角色装饰器.ts
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
Run Code Online (Sandbox Code Playgroud)
角色.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
console.log(user);
const hasRole = () => user.roles.some((role) => roles.includes(role));
return user && user.roles && hasRole();
}
}
Run Code Online (Sandbox Code Playgroud)
RolesGuardapp.module.ts通过以下方式注入到内容中:
providers: [{
provide: APP_GUARD,
useClass: RolesGuard,
}]
Run Code Online (Sandbox Code Playgroud)
我的控制器标头用于验证:
@UseGuards(AuthGuard('jwt'))
@Roles('admin')
@Get('admin')
async admin(@Request() req) {
return this.authService.me(req.user);
}
Run Code Online (Sandbox Code Playgroud)
它应该检查用户是否提供了不记名令牌并且它是活动的,jwt还将用户分配给请求用户,我可以使用@Request() req然后检索它req.user,但是当涉及到时@Roles('admin'),它会undefined在roles.guard.ts
“console.log(user)”部分中返回,所以最后,不允许用户查看给定的资源,看起来像是RoleGuard之前注入的AuthGuard('jwt'),但是请求内部有 Brearer 令牌,因此应该将其转换为用户。
我正在考虑改变我的 jwt 策略并实现 CanActivate 接口并将其写在那里,但这对我来说听起来不是一个好的解决方案,因为我想将它们分开。
我可以为您确认 是RoleGuard在 之前被调用的,AuthGuard因为 的作用域RoleGuard是全局范围的应用程序(在您定义的位置),而 的AuthGuard作用范围是本地函数。如果您不介意没有RoleGuard全局作用域,而是针对每个方法进行作用域,即使需要编写更多代码,您也可以将其添加到@UseGuards装饰器中。除此之外,就像你说的,你可以将两个守卫合并为一个,但这可能会变得混乱和笨拙。
| 归档时间: |
|
| 查看次数: |
2782 次 |
| 最近记录: |