在 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。搞定!