如何在GraphQL请求中正确传递localStorage存储的access_token
问题根因
- 两个报错本质是执行环境不匹配导致:
- 第一种配置返回未认证:getAuth钩子在请求发起时未正确读取到localStorage中的token,传递的Authorization头为无效/空值
- 第二种配置报localStorage未定义:SSR(服务端渲染)场景下,GraphQL查询在服务端Node环境执行,该环境不存在浏览器专属的localStorage API
正确实现方案
场景1:纯客户端SPA(无服务端渲染)
直接在Apollo客户端初始化时配置全局request拦截器,统一注入token即可,无需单个查询单独配置:
import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client'; import { setContext } from '@apollo/client/link/context'; const httpLink = createHttpLink({ uri: '/graphql', }); // 全局拦截注入token const authLink = setContext((_, { headers }) => { const token = localStorage.getItem('access_token'); return { headers: { ...headers, authorization: token ? `Bearer ${token}` : "", } } }); const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache() });
场景2:SSR框架(如Nuxt、Next等)
需要区分服务端/客户端执行环境,优先用Cookie存储token(Cookie可同时被服务端、客户端读取),避免直接调用localStorage:
以Nuxt3 @nuxtjs/apollo模块为例:
// plugins/apollo.ts export default defineNuxtPlugin((nuxtApp) => { // 服务端从请求头Cookie解析、客户端直接读Cookie,兼容双环境 const token = useCookie('access_token').value nuxtApp.hook('apollo:auth', ({ token: authToken }) => { // 全局自动注入所有请求的Authorization头 authToken.value = token ? `Bearer ${token}` : undefined }) })
如果需要单个查询单独配置,必须先判断执行环境:
apollo:{ users:{ query:gql` query GetUsers{ users{ uuid firstname lastname role } } `, context() { // 仅客户端环境读取localStorage if(process.client) { return { headers: { Authorization: `Bearer ${localStorage.getItem('access_token')}` } } } // 服务端环境从请求头/ Cookie 中取token,根据你所用框架的API调整即可 return {} }, }, },
验证方式
配置完成后打开浏览器控制台网络面板,查看GraphQL请求的Request Headers中是否存在Authorization: Bearer <你的有效token>字段,存在且token未过期即可正常请求。
内容的提问来源于stack exchange,提问作者MiyRon
相关产品推荐
相关产品推荐

