如何在ApolloServer上下文中获取NextAuth会话(apollo-server-micro场景)
解决ApolloServer-Micro与NextAuth会话传递的问题
导致getSession返回null的核心原因是请求未携带凭证(cookie),或者CORS配置未允许凭证传递,下面是具体修复方案:
1. 修正CORS配置,允许携带凭证
默认的micro-cors未开启凭证支持,需要显式配置credentials: true,确保跨域请求时浏览器能携带NextAuth的会话cookie:
const cors = Cors({ credentials: true, // 按需配置允许的 origin,比如你的项目域名或本地地址 origin: process.env.NEXTAUTH_URL || "http://localhost:3000" });
2. 同步ApolloServer的CORS选项
ApolloServer的createHandler自带CORS配置,需要和micro-cors保持一致,避免配置冲突导致凭证无法传递:
await apolloServer.createHandler({ path: "/api/graphql", cors: { credentials: true, origin: process.env.NEXTAUTH_URL || "http://localhost:3000" } })(req, res);
3. 确保NextAuth的会话cookie配置正确
在[...nextauth].js中,调整cookie的sameSite和secure属性,保证会话cookie能在API路由中被访问:
export default NextAuth({ session: { strategy: "jwt", // 或使用database策略 }, cookies: { sessionToken: { name: `next-auth.session-token`, sameSite: process.env.NODE_ENV === "production" ? "none" : "lax", secure: process.env.NODE_ENV === "production", }, }, // 其他配置(providers等)... });
完整修复后的代码示例
import { ApolloServer } from "apollo-server-micro"; import { getSession } from "next-auth/react"; import Cors from "micro-cors"; const apolloServer = new ApolloServer({ typeDefs, resolvers, context: async ({ req }) => { const session = await getSession({ req }); return { session }; }, }); export const config = { api: { bodyParser: false, }, }; const startServer = apolloServer.start(); // 配置CORS允许凭证 const cors = Cors({ credentials: true, origin: process.env.NEXTAUTH_URL || "http://localhost:3000" }); export default cors(async function handler(req, res) { if (req.method === "OPTIONS") { res.end(); return false; } await startServer; await apolloServer.createHandler({ path: "/api/graphql", // 同步Apollo的CORS配置 cors: { credentials: true, origin: process.env.NEXTAUTH_URL || "http://localhost:3000" } })(req, res); });
额外排查点
- 前端请求GraphQL时,需开启
credentials: include(比如Apollo Client的createHttpLink中配置credentials: "include") - 检查浏览器网络请求,确认请求头包含
Cookie字段,响应头存在Access-Control-Allow-Credentials: true和正确的Access-Control-Allow-Origin
内容的提问来源于stack exchange,提问作者Nothing here
相关产品推荐
相关产品推荐

