vue实现token无感登录

877 阅读2分钟

在 Vue.js 应用中实现 token 无感登录主要是指在 access token 过期时,通过 refresh token 自动刷新登录状态,确保用户不会因 token 过期而被迫重新登录。这里是一个基于 Axios 和 Vue 提供的状态管理工具(如 Vuex 或 Pinia)的简化流程示例:

1. 初始化项目配置

确保安装了 Axios 并将其集成到项目中作为 HTTP 请求库。

npm install axios

2. 设置 Axios 拦截器

在 Vue 项目的全局配置中设置 Axios 拦截器,用于处理响应错误中的 token 过期情况,并尝试使用 refresh token 刷新。

// src/utils/request.js 或类似的请求封装模块
import axios from 'axios';
import store from '@/store'; // 引入你的状态管理模块

const service = axios.create({
  baseURL: process.env.VUE_APP_API_BASE_URL,
  timeout: 5000,
});

service.interceptors.response.use(
  response => response,
  error => {
    const originalRequest = error.config;
    if (error.response.status === 401 && !originalRequest._retry) { // 检查是否为未授权错误且未重试过
      // 判断是否是因为 access token 过期导致的 401
      if (isTokenExpired(error)) { // isTokenExpired 是一个自定义函数,检查响应中是否有 token 过期的提示
        return new Promise((resolve, reject) => {
          store.dispatch('auth/refreshToken') // 调用状态管理中的 refreshToken action
            .then(response => {
              // 如果刷新成功,更新 axios 的 headers 并重新发送请求
              if (response.data.access_token) {
                originalRequest.headers['Authorization'] = 'Bearer ' + response.data.access_token;
                originalRequest._retry = true; // 标记已重试
                resolve(service(originalRequest)); // 重新发送请求
              } else {
                reject(error); // 若刷新失败,则继续抛出错误
              }
            })
            .catch(() => {
              // 刷新失败,比如 refresh token 也过期或无效,这时可能需要引导用户重新登录
              store.dispatch('auth/clearTokens');
              reject(error);
            });
        });
      }
    }
    return Promise.reject(error);
  },
);

export default service;

3. 状态管理(Vuex 或 Pinia)

在状态管理中维护 token 信息,并实现 refreshToken action 以及相关 mutations。

// Vuex 示例(假设使用的是 Vuex)
// store/auth.js
import axios from '@/utils/request';

export const state = () => ({
  accessToken: localStorage.getItem('accessToken') || '',
  refreshToken: localStorage.getItem('refreshToken') || '',
});

export const mutations = {
  SET_ACCESS_TOKEN(state, token) {
    state.accessToken = token;
    localStorage.setItem('accessToken', token);
  },
  SET_REFRESH_TOKEN(state, token) {
    state.refreshToken = token;
    localStorage.setItem('refreshToken', token);
  },
};

export const actions = {
  async refreshToken({ commit }) {
    try {
      const response = await axios.post('/api/auth/refresh'); // 调用后端刷新 token 的接口
      const { accessToken, refreshToken } = response.data;
      commit('SET_ACCESS_TOKEN', accessToken);
      commit('SET_REFRESH_TOKEN', refreshToken);
      return response;
    } catch (error) {
      throw error;
    }
  },
};

// ... 其他actions和mutations...

4. 使用登录和登出逻辑

在应用中实现登录和登出功能,确保在登录成功后将 access token 和 refresh token 存储到状态管理及本地存储中;登出时清除这两个 token。

总结

上述例子展示了 Vue 应用中如何利用 Axios 拦截器结合状态管理实现 token 的无感刷新。当访问 API 时遇到 401 错误,会自动尝试使用 refresh token 刷新 access token,从而达到无感知刷新登录状态的目的。同时,需要后端配合提供相应的接口来接收 refresh token 并返回新的 access token。搞定!