如何在控制器中添加多个 Nestjs RoleGuard

tec*_*ack 7 roles guard typescript angular nestjs

我有管理员、超级管理员、用户、版主的角色保护,

\n\n

这是其中一名警卫的例子。案件中的一名管理员警卫。它们按我的预期工作,但我无法在控制器中添加多个防护装置

\n\n
import\xc2\xa0{\xc2\xa0Injectable,\xc2\xa0CanActivate,\xc2\xa0ExecutionContext,\xc2\xa0HttpException,\xc2\xa0HttpStatus\xc2\xa0}\xc2\xa0from '@nestjs/common';\n\n@/Injectable()\nexport class AdminGuard implements CanActivate\xc2\xa0{\n constructor()\xc2\xa0{\xc2\xa0}\n\n canActivate(context:\xc2\xa0ExecutionContext)\xc2\xa0{\n const request\xc2\xa0=\xc2\xa0context.switchToHttp().getRequest();\n const user\xc2\xa0=\xc2\xa0request.user;\n\n if\xc2\xa0(user.usertype\xc2\xa0==\xc2\xa0'Admin')\xc2\xa0{\n return true;\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0}\n throw new HttpException('Unauthorized\xc2\xa0access',\xc2\xa0HttpStatus.BAD_REQUEST);\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0}\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

在我的控制器中,我有这个装饰器

\n\n
\xc2\xa0\n@UseGuards(AuthGuard('jwt'),\xc2\xa0AdminGuard)\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

我希望能够做这样的事情

\n\n
@UseGuards(AuthGuard('jwt'),\xc2\xa0AdminGuard, SuperAdminGuard)\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者

\n\n
@UseGuards(AuthGuard('jwt'), [AdminGuard, SuperAdminGuard, UserGuard])\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者

\n\n
\n@UseGuards(AuthGuard('jwt'), AdminGuard || SuperAdminGuard || UserGuard])\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

上述实现均无效。有更好的方法吗?也许我有什么地方做得不对。我已经检查了文档,但似乎无法使其工作

\n

Kim*_*ern 7

我建议创建一个通用的角色RolesGuard,并使用自定义元数据定义每个控制器或路由处理程序所需的角色:

@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 userType = request.user.userType;
    return roles.some(r => r === userType);

  }
}
Run Code Online (Sandbox Code Playgroud)

自定义装饰器来设置所需的角色:

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
Run Code Online (Sandbox Code Playgroud)

如何使用它?

现在您可以定义所需的角色,如下所示:

// For this route you need either Superadmin or Admin privileges
@Roles('Superadmin', 'Admin')
@UseGuards(AuthGuard('jwt'), RolesGuard)
Run Code Online (Sandbox Code Playgroud)