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

Angular拦截器中获取GraphQL查询/变更名称的实现求助

在Angular拦截器中获取GraphQL的Query/Mutation名称

我现有一个运行正常的Angular拦截器,需要在其中获取GraphQL的query或mutation名称,用于刷新令牌机制中根据对应的操作发送不同令牌。当前拦截器代码如下:

import { HttpContextToken, HttpInterceptorFn } from '@angular/common/http';
import { environment } from '../../../environments/environment'


export const REFRESHER_TOKEN_INTERCEPTOR = new HttpContextToken(() => false)
export const authInterceptor: HttpInterceptorFn = (req, next) => {

  //By dafault, the interceptor will try to pass the JWT token but for the refresherToken we must pass the refresher token instead
  const jwtToken = getJwtToken(req.context.get(REFRESHER_TOKEN_INTERCEPTOR));

  if (jwtToken) {
    var cloned = req.clone({
      setHeaders: {
        Authorization: `Bearer ${jwtToken}`
      }
    })
    return next(cloned)
  }
  return next(req);
};

实现方案

GraphQL请求的请求体中包含query/mutation的定义,我们可以从req.body中解析出操作名称,核心思路是处理请求体的两种格式(JSON对象/字符串),并提取操作标识。

修改后的拦截器代码

import { HttpContextToken, HttpInterceptorFn } from '@angular/common/http';
import { environment } from '../../../environments/environment'

export const REFRESHER_TOKEN_INTERCEPTOR = new HttpContextToken(() => false)

// 提取GraphQL操作名称的工具函数
const getGraphQLOperationName = (body: any): string | null => {
  let parsedBody = body;
  // 处理请求体为字符串的情况,先解析为JSON
  if (typeof parsedBody === 'string') {
    try {
      parsedBody = JSON.parse(parsedBody);
    } catch (e) {
      return null;
    }
  }
  // 优先读取显式的operationName字段
  if (parsedBody.operationName) {
    return parsedBody.operationName;
  }
  // 从query字符串中匹配操作名称(适配未指定operationName的情况)
  if (parsedBody.query) {
    const match = parsedBody.query.match(/^(query|mutation)\s+(\w+)/);
    return match ? match[2] : null;
  }
  return null;
};

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  let operationName: string | null = null;
  // 仅对GraphQL请求做处理(替换为你的实际GraphQL端点路径)
  if (req.url.includes(environment.graphqlUrl)) {
    operationName = getGraphQLOperationName(req.body);
  }

  // 根据操作名称切换令牌类型
  let useRefreshToken = req.context.get(REFRESHER_TOKEN_INTERCEPTOR);
  // 示例:如果是refreshToken mutation,使用刷新令牌
  if (operationName === 'refreshToken') {
    useRefreshToken = true;
  }

  const jwtToken = getJwtToken(useRefreshToken);

  if (jwtToken) {
    const cloned = req.clone({
      setHeaders: {
        Authorization: `Bearer ${jwtToken}`
      }
    })
    return next(cloned)
  }
  return next(req);
};

关键说明

  • 工具函数getGraphQLOperationName兼容两种常见的GraphQL请求格式:带显式operationName字段的请求,以及直接在query字符串中定义操作名称的请求。
  • 先判断请求URL是否指向GraphQL端点,避免对非GraphQL请求做无效解析。
  • 可根据实际业务需求,扩展operationName的判断逻辑,实现不同操作对应不同令牌的发送规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:22:12