Apollo Gateway问题:如何将子图的set-cookie头转发给客户端?
我有一个处理会话的子图微服务,通过该子图创建的Cookie存储会话,本应通过Set-Cookie头进行设置,但目前网关似乎无法将子图的Set-Cookie头转发给客户端。已确认子图返回了Set-Cookie头,但该头并未传递到客户端。
网关代码
const { ApolloServer } = require('apollo-server'); const { ApolloGateway, RemoteGraphQLDataSource } = require('@apollo/gateway'); const { readFileSync } = require('fs'); const supergraphSdl = readFileSync('./gateway/supergraph.graphql').toString(); class CookieDataSource extends RemoteGraphQLDataSource { didReceiveResponse({ response, request, context }) { const cookie = response.http.headers.get('set-cookie'); console.log("Cookie:", cookie) return response; } } const gateway = new ApolloGateway({ supergraphSdl, buildService({url}) { return new CookieDataSource({url}); } }); const server = new ApolloServer({ gateway, cors: { origin: ["http://localhost:3000", "https://studio.apollographql.com"], credentials: true }, csrfPrevention: true, }); server.listen().then(({ url }) => { console.log(`🚀 Gateway ready at ${url}`); }).catch(err => {console.error(err)});
版本信息
@apollo/gateway: ^2.1.2apollo-server: ^3.10.2
解决方案
Apollo Gateway默认不会自动将子图响应中的Set-Cookie头转发到客户端,需要在RemoteGraphQLDataSource的didReceiveResponse方法中手动提取并添加到网关的响应头中,同时要确保网关的响应上下文能正确传递这些头信息。
修改后的CookieDataSource代码
class CookieDataSource extends RemoteGraphQLDataSource { didReceiveResponse({ response, request, context }) { // 处理单个或多个Set-Cookie头的情况 const setCookieHeaders = response.http.headers.getAll('set-cookie'); if (setCookieHeaders.length) { setCookieHeaders.forEach(cookie => { context.response.headers.append('Set-Cookie', cookie); }); } return response; } }
额外注意事项
- 跨域配置中的
credentials: true已正确设置,这是客户端能接收Cookie的必要条件,同时客户端发起请求时也需要携带credentials: 'include'(比如Apollo Client需配置fetchOptions: { credentials: 'include' })。 - 若开启
csrfPrevention: true后出现Cookie传递问题,可暂时关闭测试(生产环境建议保留,需配合正确的CSRF防护配置)。
内容的提问来源于stack exchange,提问作者NateAGeek
相关产品推荐
相关产品推荐

