【问题标题】:Custom ClassSerializerInterceptor in NestJS to serialize based on user role (express req object)NestJS中的自定义ClassSerializerInterceptor根据用户角色进行序列化(表达req对象)
【发布时间】:2021-03-27 06:03:24
【问题描述】:

在 NestJS 路由中,我想根据请求(用户角色)序列化响应。这意味着我需要将选项groups: [] 传递给ClassSerializerInterceptor 中的transformToPlain 方法,这样class-transformer 才能正确返回过滤格式:

这是原始拦截器来源:https://github.com/nestjs/nest/blob/master/packages/common/serializer/class-serializer.interceptor.ts

我刚刚扩展了这个类,并根据请求将intercept 方法更改为还包括group 选项:

export class CustomClassSerializerInterceptor extends ClassSerializerInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    // @ts-ignore
    const contextOptions = this.getContextOptions(context);
    const options = {
      ...this.defaultOptions,
      ...contextOptions,
      groups: request.user.roles // Pseudo
    };
    return next
      .handle()
      .pipe(map((res: PlainLiteralObject | Array<PlainLiteralObject>) => this.serialize(res, options)));
  }
}

我的实体:

export class Content extends BaseDatabaseEntity {
  @Column()
  @Transform((type) => EContentType[type])
  type: EContentType;

  @Expose({ groups: ["MODERATOR", "ADMIN"] })
  @Column({ default: "[]", type: "json" })
  data: TContentDataColumn[];
}

这是正确的做法吗?例如 this.getContextOptions 方法在原始源代码中是私有的,所以我需要在这里执行 ts-ignore,以覆盖在我看来是大禁忌的类的默认预期隐私。

我什至应该根据用户的角色转换 API 响应,还是反模式?

【问题讨论】:

    标签: typescript nestjs interceptor


    【解决方案1】:

    您可以根据触发的路由将@SerializationOptions() 装饰器用于pass extra options。由于您似乎需要动态执行此操作,您可以使用Reflect 命名空间并设置每个请求的元数据。元数据令牌是'class_serializer:options',所以你可以做类似的事情

    Reflect.defineMetadata(
      'class_serializer:options',
      { groups: req.user.roles },
      Class.prototype,
      'method'
    );
    

    它不一定漂亮,但它可以工作

    【讨论】:

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