You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 06:30:36