Fastify+Apollo Server 4中Session跨请求共享失败的解决方法
解决Apollo Server 4 + Fastify会话跨请求不共享问题
核心原因
单个请求内会话读写正常,但跨请求丢失,本质是会话数据未被持久化到Redis,或者后续请求未正确加载会话。以下是针对性解决方案:
1. 显式保存会话修改
@mgcrea/fastify-session默认会在请求结束时自动保存会话,但Apollo的GraphQL请求处理生命周期可能导致自动保存逻辑未触发。需手动调用save()方法确保数据写入Redis:
@Query(() => Int, { nullable: true }) async test(@Ctx() { req }: MyCtx): Promise<number> { req.session.set("5", 2); await req.session.save(); // 强制保存会话到Redis return req.session.get("5") as number; }
2. 确保插件注册顺序正确
Fastify插件按注册顺序执行,必须先注册fastify-session,再注册Apollo Server,否则会话中间件无法处理GraphQL请求:
// 第一步:注册会话插件 await app.register(fastifySession, { cookieName: "qid", saveUninitialized: true, store: new RedisStore({ client: new Redis({ enableAutoPipelining: true }), }), secret: "cats", cookie: { maxAge: 31536e7, httpOnly: true, sameSite: "lax", secure: process.env.NODE_ENV === "production", }, }); // 第二步:注册Apollo Server const apollo = new ApolloServer<MyCtx>({ typeDefs, resolvers, }); await apollo.start(); app.route({ method: ["POST"], url: "/graphql", handler: async (req, reply) => { return apollo.createHandler({ context: async () => ({ req, reply }), })(req, reply); }, });
3. 验证Redis连接有效性
确认Redis客户端正常连接,避免因连接失败导致数据无法持久化:
const redisClient = new Redis({ enableAutoPipelining: true }); // 监听连接状态 redisClient.on("error", (err) => console.error("Redis连接失败:", err)); redisClient.on("connect", () => console.log("Redis连接成功")); // 传入会话存储 store: new RedisStore({ client: redisClient }),
4. 调整Cookie的secure配置
本地开发环境(HTTP协议)下,secure: "auto"可能导致浏览器拒绝保存Cookie,需根据环境动态设置:
cookie: { maxAge: 31536e7, httpOnly: true, sameSite: "lax", secure: process.env.NODE_ENV === "production", // 生产环境启用secure,开发环境禁用 },
内容的提问来源于stack exchange,提问作者UwU
相关产品推荐
相关产品推荐

