javascript NestJS:如何在中间件中获取ExecutionContext

pdkcd3nj  于 2023-09-29  发布在  Java
关注(0)|答案(1)|浏览(132)

我们正在使用NestJS为我们的NodeJS应用程序。在我们的应用程序中,我们有一些中间件/守卫/拦截器来创建用户请求上下文,验证jwt令牌,拦截请求/响应等。
我们还实现了一些自定义装饰器,为我们的端点设置元数据。在guards / intercetpors中使用这些数据非常容易,因为你在canActivate / intercept函数中有ExecutionContext。
但是我们在中间件中严重缺少这种功能。是否有机会在NestJS中间件中获取/注入ExecutionContext?
例如

export class SomeMiddleware implements NestMiddleware {
    constructor(@Inject('ExecutionContext') context: ExecutionContext) {}

    use(req, res, next) {
        // get data from context / decorator
        Reflect.getMetadata(SOME_KEY, context.getHandler());

        next();
    }
}
kokeuurv

kokeuurv1#

您可以使用cls-hooked或其他类似的模块来创建自定义上下文。为此,您可以使用上下文创建器中间件,如:

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import cls from 'cls-hooked';

@Injectable()
export class ContextCreatorMiddleware implements NestMiddleware {
  private readonly contextNamespace: cls.Namespace<Record<string, any>>;

  constructor() {
    this.contextNamespace =
      cls.getNamespace('context-name') ||
      cls.createNamespace('context-name');
  }

  use(req: Request, res: Response, next: NextFunction) {
    this.requestTracingNamespace.bindEmitter(req);
    this.requestTracingNamespace.bindEmitter(res);

    return new Promise((resolve) => {
      this.contextNamespace.run(async () => {
        this.contextNamespace.set('YOUR_KEY', YOUR_VALUE);
        resolve(next());
      });
    });
  }
}

然后,您可以在其他服务中使用您的上下文,例如:

import { Injectable } from '@nestjs/common';
import cls from 'cls-hooked';

@Injectable()
export class YourService {
  public constructor() {}

  public f1() {
    const contextNamespace = cls.getNamespace('context-name');
    const yourValue = contextNamespace?.get('YOUR_KEY');
  }
}

请记住在AppModule中应用中间件:

export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(ContextCreatorMiddleware).forRoutes('*');
  }
}

相关问题