是否可以将参数传递给 nestjs 守卫?

Alb*_*ert 7 nestjs

我试图想出一个有点可重用的守卫,看起来我需要将一个字符串参数传递给一个守卫。在nestjs中可以实现吗?

Jef*_*Chu 18

在NestJs中的Guard中使用mixin似乎是不可能的。它将抛出导出变量“RoleGuard”具有或正在使用私有名称“RoleGuardMixin”。

实际上,你可以使用setMetadata将参数一一传入,然后使用来自'@nestjs/core'的反射器从Guard中获取它。

    @Injectable()
    export class RoleGuard implements CanActivate {
        constructor(
            private reflector: Reflector,
        ) {}

        canActivate(context: ExecutionContext) {
          const roleName = this.reflector.get<string>('roleName', context.getHandler());
          return true;
        }
    }
Run Code Online (Sandbox Code Playgroud)
    @Get()
    @SetMetadata('roleName', 'developer')
    async testRoleGuard() {
      return true;
    }
Run Code Online (Sandbox Code Playgroud)

或者你可以定义一个装饰器来传递参数。

export const RoleName = (roleName: string) => SetMetadata('roleName', roleName);
Run Code Online (Sandbox Code Playgroud)
    @Get()
    @RoleName('developer')
    async testRoleGuard() {
      return true;
    }
Run Code Online (Sandbox Code Playgroud)


Jay*_*iel 16

听起来您正在寻找使用 a mixin,一个返回类的函数。我不确定你要传递什么样的参数,但这个想法是

export const RoleGuard = (role: string) => {
  class RoleGuardMixin implemenets CanActivate {
    canActivate(context: ExecutionContext) {
      // do something with context and role
      return true;
    }
  }

  const guard = mixin(RoleGuardMixin);
  return guard;
}
Run Code Online (Sandbox Code Playgroud)

mixin作为一个函数是从中导入的,@nestjs/common并且是一个将@Injectable()装饰器应用于类的包装函数

现在要使用守卫,你需要做一些类似的事情 @UseGuards(RoleGuard('admin'))

  • 只是提醒人们使用此解决方案遇到 TS 错误,可以通过更改“RoleGuard”的返回类型轻松解决该问题(即“export const RoleGuard = (role: string): Type&lt;CanActivate&gt; ...” .否则返回类型是私有类,将会失败。 (10认同)