Axios Token 设置示例

发布于:2025-07-24 ⋅ 阅读:(15) ⋅ 点赞:(0)

以下是一个完整的 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. 安全实践建议

  1. 存储位置

    javascript复制代码

    // 避免 XSS 攻击的最佳实践
    const secureStorage = {
      set: (key, value) => {
        if (window.isSecureContext) {
          // 优先使用 HttpOnly cookies(服务端设置)
        } else {
          // 次选方案:sessionStorage(标签页生命周期)
          sessionStorage.setItem(key, value);
        }
      },
      get: (key) => sessionStorage.getItem(key)
    }
    
  2. Token 自动续期

    javascript复制代码

    // 定时检查 token 有效期
    setInterval(() => {
      const token = localStorage.getItem('authToken');
      if (token && isTokenExpiringSoon(token)) {
        refreshTokenSilently();
      }
    }, 300000); // 每 5 分钟检查一次
    
  3. 敏感操作保护

    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)进行调整。关键要点:

  1. 使用 Axios 实例封装避免全局污染
  2. 拦截器自动处理 Token 注入
  3. 实现 Token 刷新机制
  4. 提供多种存储方案的安全实践
  5. 完整的错误处理流程

网站公告

今日签到

点亮在社区的每一天
去签到