以下是一个完整的 Axios Token 设置示例,涵盖全局配置、请求拦截器和单次请求设置三种方式:
1. 基础配置(推荐方案)
javascript复制代码
import axios from 'axios';
// 创建 Axios 实例
const apiClient = axios.create({
baseURL: 'https://api.yourdomain.com',
timeout: 10000,
});
// 请求拦截器(自动添加 Token)
apiClient.interceptors.request.use(config => {
// 从安全存储获取 token(如 localStorage、Vuex/Pinia、Redux 等)
const token = localStorage.getItem('authToken') || sessionStorage.getItem('authToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
} else {
console.warn('No authentication token found');
}
return config;
}, error => {
return Promise.reject(error);
});
export default apiClient;
2. 使用示例
javascript复制代码
// 使用配置好的实例发起请求
apiClient.get('/user/profile')
.then(response => {
console.log('用户数据:', response.data);
})
.catch(error => {
console.error('请求失败:', error.response?.data || error.message);
});
3. 单次请求设置 Token
javascript复制代码
// 方法 1:通过 headers 参数
axios.get('/protected/data', {
headers: {
Authorization: `Bearer ${localStorage.getItem('authToken')}`
}
});
// 方法 2:使用自定义实例
const tempClient = axios.create();
tempClient.get('/protected/data', {
headers: {
Authorization: `Bearer ${localStorage.getItem('authToken')}`
}
});
4. 完整 Vue.js 应用示例
javascript复制代码
// main.js
import { createApp } from 'vue';
import axios from 'axios';
import App from './App.vue';
const app = createApp(App);
// 全局配置 Axios
const apiClient = axios.create({
baseURL: import.meta.env.VITE_API_URL,
});
apiClient.interceptors.request.use(config => {
const token = localStorage.getItem('authToken');
token && (config.headers.Authorization = `Bearer ${token}`);
return config;
});
// 挂载到全局属性
app.config.globalProperties.$axios = apiClient;
app.mount('#app');
javascript复制代码
// AuthService.js
export default {
async login(credentials) {
const response = await axios.post('/auth/login', credentials);
// 保存 token 到 localStorage
localStorage.setItem('authToken', response.data.token);
return response.data.user;
},
logout() {
localStorage.removeItem('authToken');
},
async getUserData() {
// 使用全局配置的 axios 实例
return this.$axios.get('/user');
}
}
5. 处理 Token 过期的响应拦截器
javascript复制代码
// 添加响应拦截器
apiClient.interceptors.response.use(
response => response,
error => {
const originalRequest = error.config;
// 检测 401 错误且未重试过
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
// 使用刷新 token 获取新 access token
return axios.post('/auth/refresh-token', {
refreshToken: localStorage.getItem('refreshToken')
}).then(res => {
// 保存新 token
localStorage.setItem('authToken', res.data.accessToken);
// 更新请求头
originalRequest.headers.Authorization = `Bearer ${res.data.accessToken}`;
// 重新发起原始请求
return axios(originalRequest);
}).catch(refreshError => {
// 刷新失败则登出
store.dispatch('logout');
return Promise.reject(refreshError);
});
}
return Promise.reject(error);
}
);
6. 安全实践建议
存储位置:
javascript复制代码
// 避免 XSS 攻击的最佳实践 const secureStorage = { set: (key, value) => { if (window.isSecureContext) { // 优先使用 HttpOnly cookies(服务端设置) } else { // 次选方案:sessionStorage(标签页生命周期) sessionStorage.setItem(key, value); } }, get: (key) => sessionStorage.getItem(key) }
Token 自动续期:
javascript复制代码
// 定时检查 token 有效期 setInterval(() => { const token = localStorage.getItem('authToken'); if (token && isTokenExpiringSoon(token)) { refreshTokenSilently(); } }, 300000); // 每 5 分钟检查一次
敏感操作保护:
javascript复制代码
// 关键操作前验证密码 async function changePassword(newPassword) { const password = prompt('请确认您的密码'); await apiClient.post('/verify-password', { password }); return apiClient.put('/user/password', { newPassword }); }
7. 完整流程图
mermaid复制代码导出svg
8. 常见错误处理
javascript复制代码
// 统一错误处理
apiClient.interceptors.response.use(
response => response,
error => {
if (error.response) {
switch (error.response.status) {
case 401:
console.error('认证失败,请重新登录');
router.push('/login');
break;
case 403:
console.error('权限不足,无法访问');
break;
case 429:
console.warn('请求过于频繁,请稍后重试');
break;
default:
console.error(`请求错误: ${error.message}`);
}
} else if (error.request) {
console.error('服务器无响应', error.request);
} else {
console.error('请求配置错误', error.message);
}
return Promise.reject(error);
}
);
以上实现满足企业级应用的安全要求,可根据实际框架(React/Vue/Angular)进行调整。关键要点:
- 使用 Axios 实例封装避免全局污染
- 拦截器自动处理 Token 注入
- 实现 Token 刷新机制
- 提供多种存储方案的安全实践
- 完整的错误处理流程