如何在React组件中为Apollo Client添加授权头令牌?
嘿,我来帮你搞定这个需求!首先得先纠正你代码里一个小问题:googleAuthenticate调用后端拿token肯定是异步操作,你现在直接赋值let token = googleAuthenticate(code.code);拿到的会是一个Promise,不是实际的token值,得用async/await来处理。
接下来,要让后续所有请求都带上Authorization头,最常用的有两种方案,我给你详细讲讲:
方案一:用Axios请求拦截器(推荐,适合大部分项目)
如果你的项目用Axios发请求,这是最方便的方式。我们可以创建一个Axios实例,添加请求拦截器,每次发请求前自动把token加到Authorization头里。
步骤1:安装Axios(如果还没装)
npm install axios
步骤2:创建Axios实例并配置拦截器
可以在项目里新建一个api.js文件:
import axios from 'axios'; // 创建Axios实例 const api = axios.create({ baseURL: '你的后端API地址', // 比如http://localhost:3001/api }); // 添加请求拦截器 api.interceptors.request.use( (config) => { // 从localStorage里获取token const token = localStorage.getItem('authToken'); if (token) { // 把token加到Authorization头里,格式一般是Bearer + 空格 + token config.headers.Authorization = `Bearer ${token}`; } return config; }, (error) => { // 处理请求错误 return Promise.reject(error); } ); export default api;
步骤3:修改你的LoginForm组件
把登录函数改成异步,拿到token后存在localStorage里:
export default function LoginForm() { // 改成async函数,处理异步请求 async function userLogin(code){ try { const token = await googleAuthenticate(code.code); // 把token存在localStorage里,这样刷新页面也不会丢(如果需要持久化的话) localStorage.setItem('authToken', token); // 这里可以加登录成功后的逻辑,比如跳转到首页 // navigate('/dashboard'); // 如果用react-router的话 } catch (error) { // 处理登录失败的情况 console.log('登录出错啦:', error); } } return( <div> <GoogleLogin clientId="xyz" buttonText="Login" onSuccess={userLogin} onFailure={userLogin} cookiePolicy={'single_host_origin'} hostedDomain={"blabla.com"} responseType={"code"} /> </div> ); };
步骤4:后续请求用这个Axios实例
之后所有需要验证的API请求,都用我们创建的api实例来发:
import api from './api'; // 比如获取用户信息 async function getUserInfo() { try { const response = await api.get('/user'); console.log(response.data); } catch (error) { console.log('请求失败:', error); } }
方案二:自定义Fetch封装(适合用原生Fetch的项目)
如果你的项目用原生Fetch,我们可以封装一个自己的fetch函数,每次调用自动带上Authorization头:
步骤1:封装Fetch函数
新建fetchWithAuth.js:
export async function fetchWithAuth(url, options = {}) { // 获取token const token = localStorage.getItem('authToken'); // 合并headers,添加Authorization const headers = { 'Content-Type': 'application/json', ...options.headers, }; if (token) { headers.Authorization = `Bearer ${token}`; } // 调用原生fetch return fetch(url, { ...options, headers, }); }
步骤2:登录组件里存token(和方案一一样)
同样把token存在localStorage里,然后后续请求用fetchWithAuth代替原生fetch:
import { fetchWithAuth } from './fetchWithAuth'; async function getUserInfo() { try { const response = await fetchWithAuth('/api/user'); const data = await response.json(); console.log(data); } catch (error) { console.log('请求失败:', error); } }
额外提醒
- 如果你不想用localStorage(比如担心XSS风险),可以用
sessionStorage(关闭浏览器就清除),或者用React Context/Redux来管理token状态,这样更安全,也能在组件里直接访问token。 - 别忘了处理token过期的情况,比如后端返回401错误时,跳转到登录页重新获取token。
内容的提问来源于stack exchange,提问作者BURGERFLIPPER101
相关产品推荐
相关产品推荐

