vue实现token的无感刷新

www.jswusn.com Other 2024-08-06 17:30:06 12次浏览

  在现代的单页应用(SPA)中,用户认证是一个至关重要的部分。为了保护用户的信息安全,通常会使用JWT(JSON Web Token)进行身份验证。然而,Token通常有一定的有效期,在有效期到期后,用户需要重新登录以获取新Token,这可能会影响用户体验。为了解决这个问题,我们可以实现Token的无感刷新机制,允许用户在不知觉中自动更新Token。

  第一步:设置Axios实例

  我们将使用Axios创建一个实例,并设置请求和响应拦截器。确保你已经安装了Axios:

npm install axios

  然后创建一个 axiosInstance.js文件:

import axios from 'axios';

const axiosInstance = axios.create({
  baseURL: 'https://api.example.com', // 替换为你的 API 地址
});

// 添加请求拦截器
axiosInstance.interceptors.request.use(config => {
  const token = localStorage.getItem('token'); // 从存储中获取当前的 Token
  if (token) {
    config.headers['Authorization'] = `Bearer ${token}`; // 将 Token 加入请求头
  }
  return config;
}, error => {
  return Promise.reject(error);
});

  第二步:添加响应拦截器

  我们需要处理401错误(即未授权)并尝试刷新Token。在响应拦截器中,我们监控请求的状态,如果遇到Token过期的情况,则发起刷新Token的请求。

let isRefreshing = false;
let pendingRequests = [];

axiosInstance.interceptors.response.use(response => {
  return response;
}, async error => {
  const originalRequest = error.config;

  // 检查是否是401错误以及是否已经在刷新Token
  if (error.response.status === 401 && !isRefreshing) {
    isRefreshing = true;

    try {
      const refreshToken = localStorage.getItem('refreshToken'); // 获取 Refresh Token
      const response = await axios.post('/auth/refresh', { token: refreshToken }); // 刷新 Token 的请求

      const { token } = response.data; // 假设新的 Token 在这里返回
      localStorage.setItem('token', token); // 保存新 Token

      // 重试原始请求
      pendingRequests.forEach(callback => callback(token));
      pendingRequests = [];
      
      return axiosInstance(originalRequest); // 重发原始请求
    } catch (err) {
      // 如果刷新失败,清除 Token 并重定向到登录页面等
      localStorage.removeItem('token');
      localStorage.removeItem('refreshToken');
      window.location.href = '/login'; // 跳转到登录页
      return Promise.reject(err);
    } finally {
      isRefreshing = false;
    }
  }

  // 如果正在刷新Token,将后续请求加入队列
  if (isRefreshing) {
    return new Promise((resolve, reject) => {
      pendingRequests.push((token) => {
        originalRequest.headers['Authorization'] = `Bearer ${token}`;
        resolve(axiosInstance(originalRequest));
      });
    });
  }

  return Promise.reject(error);
});


  第三步:用户登录与登出

  当用户登录成功时,我们需要保存Token和Refresh Token。以下是一个简单的登录函数示例:

async function login(username, password) {
  const response = await axios.post('/auth/login', { username, password });
  
  const { token, refreshToken } = response.data; // 假设返回数据中包含 Token 和 Refresh Token
  localStorage.setItem('token', token);
  localStorage.setItem('refreshToken', refreshToken);
}

  用户登出时,我们需要清理存储的 Token:

function logout() {
  localStorage.removeItem('token');
  localStorage.removeItem('refreshToken');
  window.location.href = '/login'; // 跳转到登录页
}

  第四步:使用Axios实例

  最后,在你的组件或服务中使用配置好的Axios实例进行API请求。

axiosInstance.get('/some-protected-route')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });


技术分享

苏南名片

  • 联系人:吴经理
  • 电话:152-1887-1916
  • 邮箱:message@jswusn.com
  • 地址:江苏省苏州市相城区

热门文章

Copyright © 2018-2024 jswusn.com 版权所有

技术支持:苏州网站建设  苏ICP备18036849号