为什么 Nest 装饰器可以满足任何请求,即使装饰器不存在?

问题描述 投票:0回答:1

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

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 {}

事情应该是这样吗?

你能告诉我如何让守卫只在装饰者存在的路线上工作吗?

nestjs nest
1个回答
0
投票

您正在将防护注入到模块中,因此它将应用于该模块的每个控制器和每个路由处理程序。相反,您可以为每个路由处理程序使用

@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);
 }

或者你也可以直接修改你的 Permission 装饰器来应用防护。

import { applyDecorators } from '@nestjs/common';
    
export function PermissionsWithGuard(...permissions: PermissionEnum[]) {
  return applyDecorators(
    SetMetadata('permissions', permissions),
    UseGuards(PermissionGuard),
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.