Apollo Federation V2网关如何为Login mutation跳过认证检查?
Apollo Federation V2网关针对特定操作跳过认证的最佳方案
方案一:基于操作名称直接跳过认证
直接修改网关的context创建逻辑,先提取当前请求的GraphQL操作名称,判断如果是Login mutation,就跳过认证检查,其他操作仍保持原有认证逻辑。
修改后的代码示例:
context: ({ req }) => { // 从请求体获取操作名称,若客户端没传则解析查询字符串提取 const operationName = req.body?.operationName; // 复杂场景可以用graphql-js的parse函数解析查询文档,更准确 // const { parse } = require('graphql'); // const queryDoc = parse(req.body?.query); // const operation = queryDoc.definitions.find(def => def.kind === 'OperationDefinition'); // const operationName = operation?.name?.value; // 对Login mutation跳过认证 if (operationName === 'Login') { return {}; } // 其他操作执行原有认证逻辑 if (req.user) { return { user: req.user }; } else { console.error( 'Authentication error while creating GQL Context', new Date().toLocaleTimeString(), ); throw new Error('Authentication error while creating GQL Context'); } },
方案二:利用网关生命周期钩子精准控制
通过Apollo Gateway的willSendRequest钩子,结合子图信息和操作名称来控制认证逻辑。先在context里传递认证状态,再在钩子中判断是否需要跳过。
示例代码:
const gateway = new ApolloGateway({ // 子图配置... context: ({ req }) => { // 先不抛出错误,传递用户信息和认证状态 return { user: req.user, isAuthenticated: !!req.user }; }, willSendRequest({ request, context }) { // 判断是否是auth子图的Login mutation if (request.http?.url.includes('/auth') && request.operationName === 'Login') { return; // 跳过认证检查 } // 其他操作验证认证状态 if (!context.isAuthenticated) { throw new Error('Authentication error while creating GQL Context'); } } });
方案三:前置中间件过滤认证
如果网关基于Express搭建,可以在Apollo Server中间件之前加一个自定义中间件,标记Login操作跳过认证,后续context逻辑根据标记判断是否执行认证检查。
示例代码:
// Express前置中间件 app.use(async (req, res, next) => { const operationName = req.body?.operationName; if (operationName === 'Login') { req.skipAuth = true; return next(); } // 其他操作执行正常认证流程,比如解析token设置req.user const user = await verifyAuthToken(req.headers.authorization); req.user = user; next(); }); // Apollo context逻辑 context: ({ req }) => { if (req.skipAuth) { return {}; } if (req.user) { return { user: req.user }; } else { console.error( 'Authentication error while creating GQL Context', new Date().toLocaleTimeString(), ); throw new Error('Authentication error while creating GQL Context'); } },
方案推荐
优先用方案一,逻辑简单直接,不需要额外依赖或复杂配置,能快速解决Login mutation跳过认证的需求。如果需要结合子图维度做更细粒度的控制,再考虑方案二或三。
内容的提问来源于stack exchange,提问作者killjoy
相关产品推荐
相关产品推荐

