代码之家  ›  专栏  ›  技术社区  ›  Владислав

为什么Nest装饰器可以处理任何请求,即使装饰器不在场?

  •  0
  • Владислав  · 技术社区  · 11 月前

    我指出了一个地方的装饰师,但它根本不起作用。然后,我按照文档所示将监护人连接到模块。现在,监护人正在处理任何请求。

    export const Permissions = (...permissions: PermissionEnum[]) =>
      SetMetadata('permissions', permissions);
    
    @Injectable()
    export class PermissionGuard implements CanActivate {
      constructor(private reflector: Reflector) {}
    
      canActivate(
        context: ExecutionContext,
      ): boolean | Promise<boolean> | Observable<boolean> {
        const requirePermissions = this.reflector.getAllAndOverride<
          PermissionEnum[]
        >('permissions', [context.getHandler(), context.getClass()]);
        console.log(requirePermissions, 'requirePermissions');
        if (!requirePermissions) {
          throw new HttpException(
            lang.ru.http_exceptions.forbidden,
            HttpStatus.FORBIDDEN,
          );
        }
    
        const user = context.switchToHttp().getRequest();
        //console.log(context.switchToHttp(), 'switchToHttp');
        //console.log(context.switchToHttp().getRequest(), 'getRequest');
        return false;
      }
    }
    
      @HttpCode(201)
      @UseGuards(JwtAuthGuard)
      @Permissions(PermissionEnum.USER_VIEW)
      @Get('/users')
      getAll(@Query() query: AdminUserQueryDto) {
        return this.adminService.getUsers(query);
      }
    
    @Module({
     ...
      providers: [RoleService, { provide: APP_GUARD, useClass: PermissionGuard }],
      ...
    })
    export class RoleModule {}
    

    应该是这样吗?

    你能告诉我如何让警卫只在装饰师在场的路线上工作吗?

    0 回复  |  直到 11 月前
        1
  •  0
  •   Rijin    11 月前

    您正在向模块注入保护,因此它将适用于该模块的每个控制器和每个路由处理程序。相反,您可以使用 @UseGuards 每个路由处理程序的装饰器。

    @HttpCode(201)
    @UseGuards(JwtAuthGuard)
    @Permissions(PermissionEnum.USER_VIEW)
    @UseGuards(PermissionGuard)
    @Get('/users')
    getAll(@Query() query: AdminUserQueryDto) {
      return this.adminService.getUsers(query);
    }
    

    如果你不想两者都用 @Permissions @UseGuards 装饰器,您可以使用装饰器组合选项。使用该功能,您可以组合装饰器并创建一个新的装饰器。

    import { applyDecorators } from '@nestjs/common';
    
    export function PermissionsWithGuard(...permissions: PermissionEnum[]) {
      return applyDecorators(
        Permissions(permissions),
        UseGuards(PermissionGuard),
      );
    }
    

    然后在控制器中

     @HttpCode(201)
     @UseGuards(JwtAuthGuard)
     @PermissionsWithGuard(PermissionEnum.USER_VIEW)
     @Get('/users')
     getAll(@Query() query: AdminUserQueryDto) {
       return this.adminService.getUsers(query);
     }
    

    或者,您也可以直接修改您的权限装饰器来应用保护。

    import { applyDecorators } from '@nestjs/common';
        
    export function PermissionsWithGuard(...permissions: PermissionEnum[]) {
      return applyDecorators(
        SetMetadata('permissions', permissions),
        UseGuards(PermissionGuard),
      );
    }