NestJS 将 Authorization 标头传递给 HttpService

Nin*_*ics 8 http http-headers nestjs

我有一个 NestJS 应用程序,它充当前端和多个其他后端之间的代理。

我基本上希望能够将控制器中传入的@Req(请求)中的特定标头(授权)传递到 HttpService,然后与其他后端进行通信。

用户控制器(有权访问请求)-> 用户服务(注入已以某种方式选择授权标头的 httpService)-> 外部后端。

现在我需要从 @Headers 中提取令牌,然后将令牌传递给服务,该服务必须将其粘贴到所有 HttpService 调用中。

提前致谢!

Kai*_*Luo 6

除了middleware答案之外,我还有另一个版本interceptor

@Injectable()
export class HttpServiceInterceptor implements NestInterceptor {
  constructor(private httpService: HttpService) {}
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
  
    // ** if you use normal HTTP module **
    const ctx = context.switchToHttp();
    const token = ctx.getRequest().headers['authorization'];

    // ** if you use GraphQL module **
    const ctx = GqlExecutionContext.create(context);
    const token = ctx.getContext().token;

    if (ctx.token) {
      this.httpService.axiosRef.defaults.headers.common['authorization'] =
        token;
    }
    return next.handle().pipe();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用GraphQLModule,请不要忘记将令牌传递给上下文:

GraphQLModule.forRoot({
  debug: true,
  playground: true,
  autoSchemaFile: 'schema.gql',
  context: ({ req }) => {
    return { token: req.headers.authorization };
  },
}),
Run Code Online (Sandbox Code Playgroud)

准备工作做好后,我们就可以使用拦截器了

拦截器可以注入到某个控制器中:

@UseInterceptors(HttpServiceInterceptor)
export class CatsController {}
Run Code Online (Sandbox Code Playgroud)

或者注册一个全局拦截器,如下所示:

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: HttpServiceInterceptor,
    },
  ],
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)