【问题标题】:NestJS passing Authorization header to HttpServiceNestJS 将 Authorization 标头传递给 HttpService
【发布时间】:2020-09-18 04:36:39
【问题描述】:

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

我基本上希望能够将来自控制器中传入的@Req(请求)的特定标头(授权)传递给 HttpService,然后再与其他后端对话。

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

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

提前致谢!

【问题讨论】:

  • 您找到解决方案了吗?你能和我分享吗?我面临着同样的挑战。谢谢
  • @hksfho 我在下面发布了解决方案。需要注意的是,您在后台更改 Axios 实例,因此如果您的模块修改标头后控制器层,您将丢失更改。

标签: http http-headers nestjs


【解决方案1】:

除了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();
  }
}

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

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

一旦准备工作准备就绪,让我们使用拦截器

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

@UseInterceptors(HttpServiceInterceptor)
export class CatsController {}

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

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: HttpServiceInterceptor,
    },
  ],
})
export class AppModule {}

【讨论】:

    【解决方案2】:

    我不确定这是否会对您有所帮助,但也许如果您从控制器获取标头并将其放入您的服务函数中...

    // 控制器:

    @Get()
    getAll(@Request() req){
        const header = req.headers;
        return this._zoneService.sendToHttp(header);
    }
    

    也许微服务可以更好?

    【讨论】:

    • 问题是我不想对每种方法都这样做。我希望我的 HttpService 实例被告知 ONCE(中间件:esque)添加所述标头
    【解决方案3】:

    好的,我通过实际使用我最初认为的中间件设法解决了这个问题。我不是 100% 确定这是 NEST 方式,但拦截 HttpService 的底层 axios 引用就可以了:

    @Injectable()
    export class BearerMiddleware implements NestMiddleware {
      constructor(private readonly httpService: HttpService) {}
      use(req: Request, res: Response, next: Function) {
        this.httpService.axiosRef.interceptors.request.use(request => {
          request.headers = {
            ...request.headers,
            Authorization: req.headers.Authorization || '',
          };
          return request;
        });
        next();
      }
    }
    

    【讨论】:

    • No.. 每次调用 use() 时都会创建一个新的拦截器。数据不正确。
    • @hksfho 哪个更好?
    猜你喜欢
    • 2021-05-16
    • 2021-12-24
    • 1970-01-01
    • 2015-10-19
    • 2018-03-26
    • 1970-01-01
    • 2016-08-25
    • 2011-04-07
    • 2016-04-30
    相关资源
    最近更新 更多