NestJS Apollo联邦网关调用时Set-Cookie头未传递及Cookie未转发问题
要解决网关不传递请求Cookie、不透传子服务Set-Cookie的问题,直接修改你的GatewayModule配置,做以下三个关键调整:
1. 配置请求Cookie转发到子服务
在网关的gateway配置中添加buildService,自定义子服务请求的fetch逻辑,把客户端发来的Cookie头原样传递给子服务:
@Module({ imports: [ GraphQLModule.forRoot<ApolloGatewayDriverConfig>({ driver: ApolloGatewayDriver, gateway: { supergraphSdl: new IntrospectAndCompose({ subgraphs: [ { name: 'users', url: 'http://localhost:9999/graphql' }, { name: 'posts', url: 'http://localhost:9119/graphql' }, { name: 'comments', url: 'http://localhost:9229/graphql' }, ], }), // 自定义子服务请求逻辑,传递Cookie buildService({ url }) { return new RemoteGraphQLDataSource({ url, willSendRequest({ request, context }) { // 从网关请求上下文取出Cookie,传给子服务 const cookie = context.req.headers.cookie; if (cookie) { request.http.headers.set('Cookie', cookie); } }, }); }, }, }), ], }) export class GatewayModule {}
2. 透传子服务的Set-Cookie响应头到客户端
在GraphQLModule的context配置中,监听子服务的响应,把返回的Set-Cookie头添加到网关的响应头里:
@Module({ imports: [ GraphQLModule.forRoot<ApolloGatewayDriverConfig>({ driver: ApolloGatewayDriver, // 传递请求响应上下文,用于处理头信息 context: ({ req, res }) => ({ req, res }), gateway: { supergraphSdl: new IntrospectAndCompose({ subgraphs: [ { name: 'users', url: 'http://localhost:9999/graphql' }, { name: 'posts', url: 'http://localhost:9119/graphql' }, { name: 'comments', url: 'http://localhost:9229/graphql' }, ], }), buildService({ url }) { return new RemoteGraphQLDataSource({ url, willSendRequest({ request, context }) { const cookie = context.req.headers.cookie; if (cookie) { request.http.headers.set('Cookie', cookie); } }, // 处理子服务响应,透传Set-Cookie didReceiveResponse({ response, context }) { const setCookie = response.http.headers.get('Set-Cookie'); if (setCookie) { // 用append避免覆盖多个Set-Cookie context.res.append('Set-Cookie', setCookie); } return response; }, }); }, }, }), ], }) export class GatewayModule {}
3. 跨域场景补充CORS配置
如果前端和网关是跨域部署,需要在NestJS的main.ts里配置CORS,允许携带Cookie:
async function bootstrap() { const app = await NestFactory.create(AppModule); // 配置CORS app.enableCors({ origin: 'http://你的前端域名', // 替换为实际前端地址 credentials: true, // 允许携带Cookie allowedHeaders: ['Content-Type', 'Cookie'], exposedHeaders: ['Set-Cookie'], // 允许前端访问Set-Cookie头 }); await app.listen(3000); } bootstrap();
注意事项
- 子服务的Set-Cookie配置中,
SameSite属性需设为Lax或None(跨域时用None并配合Secure),避免浏览器拦截。 - 若使用HTTPS,需开启Cookie的
Secure属性。
内容的提问来源于stack exchange,提问作者saafgh
相关产品推荐
相关产品推荐

