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
相关产品推荐
相关产品推荐

