Apollo Server登录设置JWT cookie后后续请求取token为undefined如何解决
问题原因及解决方案
一、先明确正常现象
登录请求的context逻辑执行在loginUser resolver之前,所以本次登录请求的控制台打印index.js: undefined是完全正常的,你需要关注的是**登录成功后发起的第二个请求(比如添加电影的请求)**的打印,如果这个请求还是读不到cookie才是需要修复的问题。
二、后续请求读不到cookie的常见解决步骤
1. 检查GraphQL客户端是否开启了凭证携带
浏览器默认不会在跨域请求中自动携带cookie,你需要在客户端配置主动开启:
- 如果你用Apollo Client,创建HttpLink时添加
credentials: 'include'配置:
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'; const httpLink = createHttpLink({ uri: '你的Apollo Server地址', credentials: 'include' // 必须加这行 }); const client = new ApolloClient({ link: httpLink, cache: new InMemoryCache(), });
- 如果你用Apollo Sandbox(内置的 playground)测试,点击右上角设置,打开
Include credentials开关即可。
2. 修正cookie配置适配你的部署场景
你的当前cookie配置仅适配前后端同域名部署的场景,如果是前后端跨域部署(比如前端跑在localhost:3000,后端跑在localhost:4000),需要修改配置:
context.cookies.set('auth-token', token, { httpOnly: true, sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', // 跨域场景必须设为none secure: process.env.NODE_ENV === 'production', // sameSite=none时必须开启secure,生产环境用https时生效 path: '/', // 明确cookie作用路径为根路径 maxAge: 7 * 24 * 60 * 60, // 原配置6*6*60仅为36分钟,很容易过期,可按需求调整,单位为秒 });
3. 额外优化建议
你当前JWT签名时直接传入了完整的currentUser对象,包含了敏感的密码哈希字段,建议仅签名必要的用户信息避免泄露:
const token = jwt.sign( { id: currentUser.id, email: currentUser.email, name: currentUser.name }, 'supersecret', { expiresIn: '7d' } // 也可以在这里统一设置过期时间,和cookie maxAge保持一致即可 );
另外你当前context代码里的prisma;是无效语句,建议把prisma实例放到context返回值里,方便所有resolver调用:
context: ({req, res}) => { const cookies = new Cookies(req, res); const token = cookies.get('auth-token'); console.log('index.js: ', token); const user = verifyToken(token); return { cookies, user, prisma // 把prisma实例放入context }; }
内容的提问来源于stack exchange,提问作者Peter Boomsma
相关产品推荐
相关产品推荐

