NextJs环境下如何将JWT Token传入Apollo上下文
问题根因
Next.js 包含服务端渲染(SSR/SSG/ISR)逻辑,初始化 Apollo Client 的代码默认会在 Node.js 服务端环境执行一次,而 Node.js 环境没有 localStorage 全局对象,因此直接调用 localStorage.getItem 会抛出未定义错误。
方案1:仅客户端渲染(CSR)场景使用
如果对应的页面不需要服务端渲染,只在客户端侧请求接口,可以通过环境判断规避服务端执行逻辑,修改 Apollo Client 初始化代码如下:
const client = new ApolloClient({ request: (operation) => { // 仅在浏览器环境下读取 localStorage if (typeof window !== 'undefined') { const token = localStorage.getItem('id_token'); operation.setContext({ headers: { authorization: token ? `Bearer ${token}` : '', }, }); } }, uri: '/graphql', // 跨域场景需要添加以下配置,允许携带凭证 credentials: 'include', });
如果使用 Pages Router,可以给引入 Apollo Provider 的组件添加 ssr: false 的动态导入配置,彻底关闭服务端渲染:
import dynamic from 'next/dynamic' const ApolloProvider = dynamic(() => import('@apollo/client').then(mod => mod.ApolloProvider), { ssr: false })
方案2:支持服务端渲染场景使用
如果页面需要用到 SSR/SSG 等服务端能力,不建议把 token 存在 localStorage 中,改为存在 HttpOnly 加密 Cookie 里,流程如下:
- 用户登录成功时,后端返回响应同时种下带 HttpOnly、Secure、SameSite 属性的 Cookie 存储 JWT,无需前端手动存储
- Cookie 会在浏览器发起请求时自动携带,无需前端手动在请求头加 authorization 字段
- 服务端渲染阶段,Next.js 侧拿到请求头里的 Cookie,转发给 Apollo Server 即可
以 App Router 为例,服务端侧初始化 Apollo Client 的参考代码:
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'; import { headers } from 'next/headers'; const createApolloClient = () => { const httpLink = new HttpLink({ uri: '你的Apollo Server地址', credentials: 'include', // 服务端侧转发请求头里的Cookie headers: { cookie: headers().get('cookie') || '', }, }); return new ApolloClient({ link: httpLink, cache: new InMemoryCache(), ssrMode: true, }); };
注意事项
- 使用 Cookie 存储 JWT 时必须开启 HttpOnly 属性,避免 XSS 攻击窃取 token
- 跨域场景下需要同时配置 Apollo Client 的
credentials: 'include'和后端接口的 CORS 允许凭证规则 - 敏感操作的接口必须在服务端侧校验 JWT 有效性,不要完全依赖前端逻辑
内容的提问来源于stack exchange,提问作者Craig5117
相关产品推荐
相关产品推荐

