React中OpenAPI生成的Axios TS客户端如何配置JWT令牌?
配置OpenAPI生成的TypeScript客户端全局携带JWT令牌
核心思路:复用全局Configuration实例
OpenAPI生成的TypeScript客户端(以ts-axios模板为例)中,所有继承BaseApi的控制器类,构造函数都接受一个Configuration对象作为参数。我们只需要创建一个全局共享的Configuration实例,在获取JWT后更新其token配置,再将这个实例传入所有API类的构造函数,就能实现所有请求自动携带令牌。
具体实现步骤
1. 创建全局API配置文件
先初始化一个全局的Configuration实例,预留token更新的方法:
// src/api/config.ts import { Configuration } from './generated-api'; // 替换为你的生成代码路径 // 初始化配置,可提前设置basePath覆盖默认值 export const apiConfig = new Configuration({ basePath: process.env.REACT_APP_API_BASE_URL, // 后端API基础地址 accessToken: '' // 初始为空,后续登录后更新 }); // 提供更新token的方法 export const updateApiToken = (token: string) => { apiConfig.accessToken = token; };
2. 登录后更新全局token
在登录接口返回JWT后,调用updateApiToken更新配置,同时可将token存入本地存储避免刷新丢失:
// 登录逻辑示例 const handleLogin = async (credentials: { username: string; password: string }) => { const res = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(credentials) }); const data = await res.json(); if (data.token) { updateApiToken(data.token); localStorage.setItem('jwtToken', data.token); } };
3. 页面刷新时恢复token
在App初始化时,从本地存储读取token并同步到全局配置:
// src/App.tsx import { apiConfig } from './api/config'; import { useEffect } from 'react'; function App() { useEffect(() => { const savedToken = localStorage.getItem('jwtToken'); if (savedToken) { apiConfig.accessToken = savedToken; } }, []); // ... 其他组件渲染逻辑 }
4. 实例化API类时传入全局配置
所有继承BaseApi的控制器类,都使用同一个全局apiConfig实例:
// src/api/userApi.ts import { UserApi } from './generated-api'; import { apiConfig } from './config'; // 全局复用的UserApi实例 export const userApi = new UserApi(apiConfig); // 使用示例 const fetchUserProfile = async () => { try { const res = await userApi.getUserProfile(); return res.data; } catch (err) { // 错误处理逻辑 } };
关于构造函数配置与默认值覆盖的说明
Configuration类的核心参数及覆盖规则:
basePath: 传入后会直接覆盖生成代码中默认的API基础路径(即OpenAPI Spec里的servers.url)accessToken: 设置后,所有请求会自动带上Authorization: Bearer {token}头,优先级高于手动在headers里添加的Authorization字段headers: 自定义全局请求头,会和accessToken生成的头合并,不会被覆盖axiosInstance: 如果需要复用你原来的自定义Axios实例(比如旧的拦截器逻辑),可以传入这个参数。此时客户端会完全使用你提供的Axios实例,内部默认的实例会被忽略,适合需要保留token过期刷新、请求重试等原有逻辑的场景:
// 复用原有Axios拦截器示例 import axios from 'axios'; import { Configuration } from './generated-api'; const customAxios = axios.create({ baseURL: process.env.REACT_APP_API_BASE_URL }); // 请求拦截器自动加token customAxios.interceptors.request.use(config => { const token = localStorage.getItem('jwtToken'); if (token) config.headers.Authorization = `Bearer ${token}`; return config; }); // 响应拦截器处理token过期 customAxios.interceptors.response.use( res => res, async err => { if (err.response?.status === 401) { const newToken = await refreshToken(); // 你的刷新token逻辑 localStorage.setItem('jwtToken', newToken); err.config.headers.Authorization = `Bearer ${newToken}`; return customAxios(err.config); } return Promise.reject(err); } ); export const apiConfig = new Configuration({ axiosInstance: customAxios });
内容的提问来源于stack exchange,提问作者Spongi
相关产品推荐
相关产品推荐

