React+Apollo Client设置GraphQL请求头Authorization无效问题
我在基于React 18.3.1、Vite、@apollo/client 3.11.8并部署于Docker的项目中,尝试用setContext和ApolloLink两种方式给GraphQL请求头添加Authorization字段,但浏览器里查看请求时完全看不到这个字段。我已经通过ApolloProvider配置了Apollo Client,但实际发送请求用的是Axios,所有尝试都没效果。
相关代码
HttpLink配置
import { ApolloClient, InMemoryCache, HttpLink, ApolloLink, } from '@apollo/client'; import { setContext } from '@apollo/client/link/context'; const httpLink = new HttpLink({ uri: 'http://localhost:4000/graphql', });
setContext方式尝试
const authMiddleware = setContext(async (_, { headers }) => { const token = localStorage.getItem('token'); return { headers: { ...headers, 'Authorization': `Bearer ${token}` || '', }, }; }); const link = ApolloLink.from([authMiddleware, httpLink]); export const client = new ApolloClient({ link, cache: new InMemoryCache(), });
ApolloLink方式尝试
const authMiddleware = new ApolloLink((operation, forward) => { // add the authorization to the headers const token = localStorage.getItem('token'); operation.setContext(() => ({ headers: { 'Authorization': `Bearer ${token}` || '', }, })); return forward(operation); }); const link = ApolloLink.from([authMiddleware, httpLink]); export const client = new ApolloClient({ link, cache: new InMemoryCache(), });
ApolloProvider配置
import { ApolloProvider } from '@apollo/react-hooks'; import { client } from './config/graphql.ts'; ReactDOM.createRoot(document.getElementById('root')!).render( <ApolloProvider client={client}> <React.StrictMode> <App /> </React.StrictMode> </ApolloProvider>
实际请求代码
const response = await axios.post('http://localhost:4000/graphql', { query: GET_USERS, });
请求头无Authorization字段,截图如下:
问题原因
你配置的Apollo Client中间件只对Apollo Client自身发起的请求生效(比如useQuery、useMutation这些Apollo hooks发送的请求)。但实际你用Axios直接调用接口,完全绕开了Apollo Client的链路,所以之前配置的Authorization头不会被自动添加到Axios请求里。
解决方案
方案1:改用Apollo Client发送请求
直接使用Apollo提供的API发起请求,这样之前配置的中间件会自动处理请求头:
// 组件内用hooks import { useQuery } from '@apollo/client'; import { GET_USERS } from './your-queries'; const { loading, error, data } = useQuery(GET_USERS);
或者直接用client实例调用:
import { client } from './config/graphql.ts'; const response = await client.query({ query: GET_USERS });
方案2:给Axios请求手动添加Authorization头
如果必须用Axios,需要在请求时手动带上token,或者配置全局拦截器统一处理:
单次请求手动添加
const token = localStorage.getItem('token'); const response = await axios.post('http://localhost:4000/graphql', { query: GET_USERS, }, { headers: { 'Authorization': token ? `Bearer ${token}` : '' } });
全局拦截器统一配置
import axios from 'axios'; // 创建Axios实例 const apiClient = axios.create({ baseURL: 'http://localhost:4000' }); // 添加请求拦截器,自动注入token apiClient.interceptors.request.use((config) => { const token = localStorage.getItem('token'); if (token) { config.headers['Authorization'] = `Bearer ${token}`; } return config; }, (error) => { return Promise.reject(error); }); // 后续用这个实例发请求 const response = await apiClient.post('/graphql', { query: GET_USERS });
内容的提问来源于stack exchange,提问作者mohamed nageh
相关产品推荐
相关产品推荐

