NestJS 拦截器 - 将数据附加到传入请求 Header 或 Body

NestJS Interceptor - Append data to incoming request Header or Body

我正在尝试修改 NestJS 传入请求并将一些数据附加到 header 或 Body。我能够用我的数据替换所有 body 数据,但我想附加而不是删除传入的 body 数据。

这是我的代码

export class MyInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest();
    
    
    const token = request.headers['authorization'];
    if (token) {
      const decoded = jwt_decode(token);
      request.body['userId'] = decoded['id'];
    }

    return next.handle();
  }
}

提前致谢

我添加了两个示例,因为在 运行 测试拦截器之后,它顺利通过了。当然,我的示例将与您的设置大不相同,但是,希望它能给您足够的洞察力:

测试文件:


  test('should not mutate entire request body object', () => {
    const dto = {
      username: 'testuser',
      email: 'test@domain.com',
    };

    const headers = {
      authorization: 'Bearer sdkfjdsakfjdkjfdal',
    };

    return request(app.getHttpServer())
      .post('/')
      .send(dto)
      .set(headers)
      .expect(({ body }) => {
        expect(body.userId).toBeDefined();
        delete body.userId;

        expect(body).toStrictEqual(dto);
      });
  });

我理解您的问题是试图获取有关经过身份验证的用户的信息,return it/use 稍后?但是,您当前的实现似乎完全覆盖了 request.body 而不是将 属性 附加到原始对象。

拦截器:



@Injectable()
export class HttpRequestBodyInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable {
    const request = context.switchToHttp().getRequest();
    const token = request.headers['authorization'];

    if (token) {
      // decode token
      request.body['userId'] = 'user_123456789';
    }

    return next.handle();
  }
}
</pre>

控制器:


@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Post()
  @UseInterceptors(HttpRequestBodyInterceptor)
  getHello(@Req() req): string {
    return req.body;
  }
}
</pre>

这个 return 是正确的答案,测试将通过。但是,您可能会发现更可靠的解决方案是:


@Injectable()
export class HttpRequestBodyInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable {
    const request = context.switchToHttp().getRequest();
    const token = request.headers['authorization'];

    if (token) {
      // decode token
      request.userId = 'user_123456789';
    }

    return next.handle();
  }
}
</pre>

然后通过以下方式在您的控制器中访问它:


@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Post()
  @UseInterceptors(HttpRequestBodyInterceptor)
  getHello(@Req() req) {
    return {
      userId: req.userId,
      ...req.body,
    };
  }
}
</pre>

最后,如果您对拦截器的唯一需求是获取 userId 属性,您可能会发现 https://docs.nestjs.com/security/authentication#jwt-functionality 很有用。