【问题标题】:Is there any way to access arguments of handler method in a NestJS guard?有什么方法可以访问 NestJS 守卫中处理程序方法的参数?
【发布时间】:2022-01-18 12:39:58
【问题描述】:

我想在 NestJS 中实现一个智能守卫,它可以根据在特殊方法注释中声明的决策保护方法执行。

例如用例是:

普通用户只能更改自己的用户信息

管理员可以更改任何用户信息

我想通过声明方式指定决策:使用注释。我几乎已经完成了实现,这个需求可以这样声明:

@Put('user')
@UseGuards(HttpBasicAuthGuard, DecisionGuard)
@DecisionExpr(new Decisions(Op.OR, [
  new RootDecision(Role.ADMIN),
  new CurrentUserDecision({ sourceParamId: 'user', func: (user: User) => user.id}),
]))
updateUser(@ParamId('user') @Body() u: User, @ParamId('etc') etc): any {
  // call user service and update user in model
}
  • 已声明的决策通过以下方式存储到处理程序方法的元数据中 '@DecisionExpr'。

  • 参数索引由'@ParamId'收集并存储到
    处理方法的元数据。

  • 决策由可以访问当前的决策卫士评估
    来自 Request 的用户和权限(通过 ExecutionContext),它还可以 从
    轻松访问决策和确定的参数索引 元数据。

唯一的问题是如何从 DecisionGuard 访问处理程序方法的参数。 handler 方法的参数包含可以与当前用户进行比较并为 DecisionGuard 做出决定的数据。

有可能吗?

我发现的唯一方法是实现方法装饰器并通过更改 PropertyDescriptor.value(方法装饰器的第三个参数)来调用自定义方法:

export const DecisionExpr = (data: Decision): MethodDecorator => {
    ...
    const childFunction = descriptor.value;
    descriptor.value = (...args: any[]) => {
      console.log('DecisionExpr child function - args:', args);
      // call original method
      return childFunction.apply(this, args);
    };
}

但是这个解决方案的问题是自定义方法只在警卫之后调用。

我最后的机会是将这种保护从 DecisionGuard 转移到 DecisionExpr 方法装饰器的自定义方法中 - 但我不喜欢它。我不想引入新的方法保护模式。

【问题讨论】:

    标签: annotations nestjs decorator


    【解决方案1】:

    也许我会尝试这个解决方案来满足我的要求: https://docs.nestjs.com/security/authorization#integrating-casl

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多