You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将GraphQL请求头传递给NestJS中的Axios后续请求?

如何将GraphQL请求头传递给Axios后端请求

以下是针对你的请求链路(Angular Apollo Client → NestJS GraphQL Server → Axios 外部后端)的具体实现方案:

1. 解析器层获取请求头并传递给服务

在NestJS的GraphQL解析器中,通过@Context()装饰器获取请求上下文,提取需要传递的请求头,再传给服务层方法:

import { Query, Resolver, Context, Args } from '@nestjs/graphql';
import { UsersService } from './users.service';
import { UsersArgsDto } from './dto/users-args.dto';
import { UserDto } from './dto/user.dto';
import { Request } from 'express';

@Resolver(() => UserDto)
export class UsersResolver {
  constructor(private readonly usersService: UsersService) {}

  @Query(() => [UserDto])
  async users(
    @Args() args: UsersArgsDto,
    @Context() context: { req: Request },
  ) {
    // 提取需要传递的请求头(比如Authorization)
    const forwardHeaders = {
      Authorization: context.req.headers.authorization,
      // 可添加其他需要传递的头,如X-Request-ID、User-Agent等
    };
    return this.usersService.getAllUsers(args, forwardHeaders);
  }
}

2. 服务层接收请求头并注入Axios请求

修改你的getAllUsers方法,新增参数接收请求头,然后将其合并到Axios的请求配置中:

getAllUsers(
  args: UsersArgsDto,
  forwardHeaders: Record<string, string>, // 新增参数接收请求头
): Observable<DataResponse<UserDto[]>> {
  const queryParams = new URLSearchParams();

  this.getQueryFilterParams<UsersQueryFilterInput>(
    queryParams,
    args.queryFilters,
  );
  this.getPaginationParams(queryParams, args.pagination);
  this.getSortingParams(queryParams, args.sort);

  return this.httpService
    .get('/users', {
      ...this.globalConfig,
      params: queryParams,
      headers: {
        ...this.globalConfig.headers, // 保留全局配置的请求头
        ...forwardHeaders, // 合并从GraphQL请求传来的头
      },
    })
    .pipe(
      map((data) => data.data),
      validateObject(DataResponse<UserDto[]>),
      catchError((err) => {
        throw err;
      }),
    );
}

3. 全局自动传递方案(可选)

如果不想每个解析器都手动传递请求头,可以用AsyncLocalStorage结合NestJS拦截器实现全局自动注入:

步骤3.1 创建请求头拦截器

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { AsyncLocalStorage } from 'async_hooks';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class RequestHeaderInterceptor implements NestInterceptor {
  constructor(private readonly als: AsyncLocalStorage<Record<string, string>>) {}

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const gqlCtx = GqlExecutionContext.create(context);
    const req = gqlCtx.getContext().req;
    // 存储需要传递的请求头到异步本地存储
    const headersToForward = {
      Authorization: req.headers.authorization,
    };
    return this.als.run(headersToForward, () => next.handle());
  }
}

步骤3.2 注册拦截器和AsyncLocalStorage

在根模块中提供AsyncLocalStorage并注册全局拦截器:

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { AsyncLocalStorage } from 'async_hooks';
import { RequestHeaderInterceptor } from './request-header.interceptor';

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

步骤3.3 服务层从AsyncLocalStorage获取请求头

import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { AsyncLocalStorage } from 'async_hooks';

@Injectable()
export class UsersService {
  constructor(
    private readonly httpService: HttpService,
    private readonly als: AsyncLocalStorage<Record<string, string>>,
  ) {}

  getAllUsers(
    args: UsersArgsDto,
  ): Observable<DataResponse<UserDto[]>> {
    const queryParams = new URLSearchParams();

    this.getQueryFilterParams<UsersQueryFilterInput>(
      queryParams,
      args.queryFilters,
    );
    this.getPaginationParams(queryParams, args.pagination);
    this.getSortingParams(queryParams, args.sort);

    // 从异步本地存储中获取请求头
    const forwardHeaders = this.als.getStore() || {};

    return this.httpService
      .get('/users', {
        ...this.globalConfig,
        params: queryParams,
        headers: {
          ...this.globalConfig.headers,
          ...forwardHeaders,
        },
      })
      .pipe(
        map((data) => data.data),
        validateObject(DataResponse<UserDto[]>),
        catchError((err) => {
          throw err;
        }),
      );
  }
}

注意事项

  • 仅传递必要的请求头,避免泄露敏感信息
  • 若涉及跨域,需在NestJS的CORS配置中添加允许接收的请求头(如Authorization)
  • AsyncLocalStorage需要Node.js 12.17.0及以上版本支持

内容的提问来源于stack exchange,提问作者frankfullstack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 00:40:10