NodeJS NestJS setMetadata无法从authGuard运行

kmpatx3s  于 2023-01-04  发布在  Node.js
关注(0)|答案(1)|浏览(123)

我有一些装饰器,当调用时,我想setMetadata在我的日志中使用它,在我的控制器中,我有这些:

@Post("somePath")
  @Permission("somePermission")
  @UseGuards(JwtAuthGuard)
  @HttpCode(200)
  @Grafana(
    "endpoint",
    "functionalmap"
  )
  async getSubscriptionFromPwebFormFilter(
    @Body(ValidationPipe) someDto: someDtoType
  ): Promise<ISuccessResponse> {
    // some logic
  }

在我的装饰器中,我想将一些数据设置到元数据中,以便在我的日志记录接收器中使用,
Grafana装饰工:

export const Grafana = (functionalMap: string, endpoint: string) =>
    applyDecorators(
      SetMetadata("endpoint", endpoint),
      SetMetadata("functionalMap", functionalMap)
    );

AuthGuard装饰器:

@Injectable()
  export class JwtAuthGuard extends AuthGuard("jwt") {
    constructor(
      private readonly reflector: Reflector,
      private readonly someService: SomeService
    ) {
      super();
    }

    public async canActivate(context: ExecutionContext): Promise<boolean> {
      const role = this.reflector.get<string>("permission", context.getHandler());
      const request = context.switchToHttp().getRequest();
      const { valueToLog } = request.body;
      const jwtToken = request.headers.authorization;

      console.log("check value exist", valueToLog);
      SetMetadata("valueToLog", valueToLog);
  }

现在,在我的日志拦截器中,我以这种方式获取元数据的所有值:

@Injectable()
    export default class LoggingInterceptor {
      constructor(private readonly reflector: Reflector) {}

      intercept(context: ExecutionContext, next: CallHandler) {
        const executionStart = Date.now();

        return next.handle().pipe(
          tap((responseData) => {
            const response = context.switchToHttp().getResponse<ServerResponse>();
            const { statusCode } = response;
            const valueToLog = this.reflector.get(
              "valueToLog",
              context.getHandler()
            ); // this is undefined
            const endpoint = this.reflector.get("endpoint", context.getHandler()); // this have value
            const functionalMap = this.reflector.get(
              "functionalMap",
              context.getHandler()
            ); // this have value
            
            ... 
            // some logic
          })
        );
      }
    }

在我的示例中,可以从反射器检索endpoint和functionalMap的值,但是valueToLog显示为未定义,
元数据的设置对auth guard装饰器不起作用吗?

mccptt67

mccptt671#

在本说明中,我将使用术语"装饰器",因此我将首先定义它。
装饰器是接受有关装饰声明的信息的函数。
例如:

function ClassDecorator(target: typeof DecoratedClass) {
  // do stuff
}

// it can then be used like this
@ClassDecorator
class DecoratedClass {}

当调用@SetMetadata(key, value)时,它返回一个装饰器。像SetMetadata这样的函数被称为装饰器工厂。
装饰器使用@expression的形式,其中expression的计算结果必须是一个函数,该函数将在运行时使用有关装饰声明的信息进行调用。
在示例中,我们调用了SetMetadata("valueToLog", valueToLog)。这将返回一个装饰器。装饰器必须与装饰声明的相关信息一起调用。要真正附加元数据,可以执行以下操作:

SetMetadata("valueToLog", valueToLog)(context.getHandler());

相关问题