前端双 Token 无感刷新详解

在现代的 web 开发中,用户体验和安全性始终是开发者关注的重点。无感刷新通过双 Token(Access Token 和 Refresh Token)的方案,实现了在用户使用过程中无需频繁登陆的良好体验。本文将详细介绍双 Token 的机制,以及如何在前端实现无感刷新。

1. 双 Token 机制简介

双 Token 机制通常分为 Access Token 和 Refresh Token:

  • Access Token:用于访问受保护资源的令牌,通常有效期较短(例如 15 分钟)。每次用户需要进行 API 请求时,都需要提供 Access Token。

  • Refresh Token:用于获取新的 Access Token,通常有效期较长(例如 7 天或 30 天)。当 Access Token 过期时,可以使用 Refresh Token 来获取新的 Access Token。

这种机制的好处在于,即使 Access Token 被盗,也因其短暂的有效期降低了风险。同时,通过 Refresh Token,用户无需频繁登录,也提供了较为流畅的用户体验。

2. 如何实现双 Token 无感刷新

在前端实现双 Token 无感刷新,主要分为以下几个步骤:

  1. 登录时获取 Token:用户输入用户名和密码进行登录,服务器验证后返回 Access Token 和 Refresh Token。

  2. 存储 Token:将获取的两个 Token 存储在浏览器的 localStorage 或 sessionStorage 中(注意,Refresh Token 应该尽量避免暴露)。

  3. 使用 Access Token 访问 API:每次需要访问 API 时,将 Access Token 附加到请求头中。

  4. 处理 Access Token 过期:在前端判断 Access Token 是否过期,如果过期,使用 Refresh Token 请求新的 Access Token。

  5. 更新 Token:将新的 Access Token 更新到浏览器存储中。

3. 代码示例

以下是一个简单的前端双 Token 无感刷新示例代码,假设使用的是 axios 作为 HTTP 请求库。

import axios from 'axios';

// 登录函数
async function login(username, password) {
    const response = await axios.post('/api/login', { username, password });
    // 假设返回的数据中有 accessToken 和 refreshToken
    const { accessToken, refreshToken } = response.data;

    localStorage.setItem('accessToken', accessToken);
    localStorage.setItem('refreshToken', refreshToken);
}

// 请求拦截器
axios.interceptors.request.use(async (config) => {
    const accessToken = localStorage.getItem('accessToken');
    // 将 accessToken 添加到请求头中
    if (accessToken) {
        config.headers['Authorization'] = `Bearer ${accessToken}`;
    }
    return config;
}, (error) => {
    return Promise.reject(error);
});

// 响应拦截器
axios.interceptors.response.use(response => {
    return response;
}, async (error) => {
    const originalRequest = error.config;

    // 检查是否因为 accessToken 过期而导致的错误
    if (error.response.status === 401 && !originalRequest._retry) {
        originalRequest._retry = true; // 避免递归调用
        const refreshToken = localStorage.getItem('refreshToken');
        try {
            const response = await axios.post('/api/refresh', { refreshToken });
            const { accessToken } = response.data;

            // 更新 Access Token
            localStorage.setItem('accessToken', accessToken);
            // 重新设置请求头并重试原请求
            originalRequest.headers['Authorization'] = `Bearer ${accessToken}`;
            return axios(originalRequest);
        } catch (refreshError) {
            // 如果刷新失败,清除 Token,并跳转到登录页
            localStorage.removeItem('accessToken');
            localStorage.removeItem('refreshToken');
            window.location.href = '/login';
        }
    }
    return Promise.reject(error);
});

// 示例调用 API
async function getUserData() {
    try {
        const response = await axios.get('/api/user');
        console.log(response.data);
    } catch (error) {
        console.error('请求失败:', error);
    }
}

4. 总结

使用双 Token 机制进行无感刷新是一种有效的方法,可以在保证安全性的同时提高用户体验。在实现过程中,我们可以利用 HTTP 请求拦截器,轻松处理 Access Token 的过期和刷新。通过这样的方式,用户在使用应用时,可以感受到流畅的操作体验,而无需重复登录,提高了整体的使用满意度。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部