【问题标题】:How to add multiple Nestjs RoleGuards in controllers如何在控制器中添加多个 Nestjs RoleGuard
【发布时间】:2020-09-02 05:26:52
【问题描述】:

我有 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])

上述实现均无效。有没有更好的方法来解决它?也许有些事情我做的不对。我已经检查了文档,但我似乎无法使其工作

【问题讨论】:

  • @UseGuards(A, B, C) 中,如果A 返回false,则不会转到B。所以为了继续,所有都必须返回true。您可能希望这样处理:if (user.usertype === 'Admin' || user.usertype) { return true },以便可以调用下一个守卫。
  • 您的建议奏效了。我试了一下。但我会选择@kim-kern

标签: angular typescript nestjs roles guard


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    Kim 回答的另一种方法是使用MixinAuthGuard 本身使用了 mixin 概念。

    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'))
    
    

    【讨论】:

      猜你喜欢
      • 2022-10-15
      • 2016-10-30
      • 2020-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      相关资源
      最近更新 更多