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

How to add multiple Nestjs RoleGuards in controllers

我有 ADMIN、SUPERADMIN、USER、MODERATORS 的角色保护,

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

import { Injectable, CanActivate, ExecutionContext, HttpException, HttpStatus } from '@nestjs/common';

@/Injectable()
export class AdminGuard implements CanActivate {
 constructor() { }

 canActivate(context: ExecutionContext) {
 const request = context.switchToHttp().getRequest();
 const user = request.user;

 if (user.usertype == 'Admin') {
 return true;
        }
 throw new HttpException('Unauthorized access', HttpStatus.BAD_REQUEST);
    }
}

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

 
@UseGuards(AuthGuard('jwt'), AdminGuard)

我希望能够做这样的事情

@UseGuards(AuthGuard('jwt'), AdminGuard, SuperAdminGuard)

@UseGuards(AuthGuard('jwt'), [AdminGuard, SuperAdminGuard, UserGuard])


@UseGuards(AuthGuard('jwt'), AdminGuard || SuperAdminGuard || UserGuard])

None 以上实现有效。有更好的方法吗?也许我做的不对。我已经检查了文档,但似乎无法正常工作

我建议创建一个通用的 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);

  }
}

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

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);

如何使用?

现在您可以按如下方式定义所需的角色:

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

Kim 没有回答的另一种方法是使用 Mixin。 mixin 概念由 AuthGuard 本身使用。

export const UserTypeGuard: (...types: string[]) => CanActivate = createUserTypeGuard;

function createUserTypeGuard(...types: string[]) {
    class MixinUserTypeGuard implements CanActivate {
        canActivate(context: ExecutionContext) {
            const user = context.switchToHttp().getRequest().user;
            return types.some(type => user.userType === type);
        }
    }
}

用法:

@UseGuards(AuthGuard('jwt'), UserTypeGuard('SuperAdmin', 'Admin'))