当前位置: 首页 > news >正文

双重token自动续期解决方案

Token自动续期实现方案详解

Token自动续期是提升用户体验和保障系统安全的关键机制,其核心在于无感刷新和安全可控。以下从原理、实现方案、安全措施和最佳实践四个维度展开说明:

一、核心原理:双Token机制

Token自动续期通常采用 Access Token(访问令牌) + Refresh Token(刷新令牌) 的双Token方案:

  • Access Token:短期有效(如15分钟),用于直接访问受保护资源。
  • Refresh Token:长期有效(如30天),仅用于获取新的Access Token。

当用户请求资源时,服务端验证Access Token有效性:

  1. 有效:直接响应请求。
  2. 过期:客户端使用Refresh Token申请新Access Token,无需用户重新登录。

二、实现方案详解

1. 后端实现流程

(1)登录时生成双Token

// 生成Access Token(15分钟有效期)
String accessToken = JwtUtil.sign(username, secret, 15 * 60 * 1000);
// 生成Refresh Token(30天有效期)
String refreshToken = JwtUtil.sign(username, secret, 30 * 24 * 60 * 60 * 1000);
// 存储到Redis(Access Token过期时间设为双倍,用于续期判断)
redisUtil.set("access_token:" + userId, accessToken, 30 * 60); // 30分钟
redisUtil.set("refresh_token:" + userId, refreshToken, 30 * 24 * 60 * 60); // 30天


(2)请求拦截校验与续期

public boolean preHandle(HttpServletRequest request) {
    String token = request.getHeader("Authorization");
    
    // 1. 检查Access Token是否存在
    if (token == null) return false;
    
    // 2. 验证Token有效性
    try {
        JwtUtil.verify(token, secret);
    } catch (TokenExpiredException e) {
        // 3. Token过期但仍在Redis中,触发续期
        String cachedToken = redisUtil.get("access_token:" + userId);
        if (cachedToken != null && cachedToken.equals(token)) {
            String newToken = JwtUtil.sign(username, secret, 15 * 60 * 1000);
            redisUtil.set("access_token:" + userId, newToken, 30 * 60);
            request.setAttribute("new_token", newToken); // 返回新Token给前端
        } else {
            // Redis中Token已失效,需重新登录
            return false;
        }
    }
    return true;
}

2. 前端实现流程

(1)请求拦截器逻辑

axios.interceptors.response.use(response => {
    // 检查Token是否即将过期(例如剩余1分钟)
    const token = localStorage.getItem('access_token');
    const decoded = jwtDecode(token);
    const expireTime = decoded.exp * 1000;
    const now = Date.now();
    
    if (expireTime - now < 60 * 1000) {
        // 自动调用刷新接口
        return axios.post('/refresh_token', { refresh_token: localStorage.getItem('refresh_token') })
            .then(res => {
                // 更新本地Token并重试原请求
                localStorage.setItem('access_token', res.data.new_token);
                return axios(request.config);
            });
    }
    return response;
}, error => {
    // 处理Token失效或刷新失败
    if (error.response.status === 401) {
        redirectToLogin();
    }
    return Promise.reject(error);
});

(2)刷新Token接口调用

async function refreshToken() {
    try {
        const res = await axios.post('/refresh_token', {
            refresh_token: localStorage.getItem('refresh_token')
        });
        localStorage.setItem('access_token', res.data.new_token);
        return true;
    } catch (error) {
        logout(); // 刷新失败则退出登录
        return false;
    }
}

三、安全措施

  1. 传输安全:全程使用HTTPS防止Token被截获。
  2. 存储安全:
    • 前端:Refresh Token存储在HttpOnly Cookie中,避免XSS攻击。
    • 后端:Token加密存储,Redis设置访问权限。
  3. 生命周期管理:
    • Access Token:15分钟有效期,Redis缓存30分钟。
    • Refresh Token:30天有效期,支持续期次数限制(如最多刷新50次)。
  4. 黑名单机制:用户注销或修改密码时,将Refresh Token加入黑名单。

四、最佳实践

  1. 续期触发策略:
    • 时间阈值:Token剩余1分钟时触发刷新。
    • 操作感知:用户持续操作(如每5分钟有请求)自动续期。
  2. 兜底逻辑:
    • 强制重新登录:超过72小时未操作,即使Refresh Token有效也需重新认证。
    • 刷新次数限制:防止Refresh Token被无限续期。
  3. 监控与告警:
    • 监控Token刷新频率,异常高频触发告警。
    • 记录刷新日志,便于审计。

五、方案优势

维度传统单Token方案双Token自动续期方案
用户体验频繁登录打断操作无感刷新,操作连贯
安全性长期有效Token风险高短期Access Token降低泄露影响
服务端压力每次请求需解密验证续期操作减少重复认证

总结:Token自动续期通过双Token机制、缓存校验和前后端协作,实现了安全与体验的平衡。实际部署时需结合业务场景调整Token有效期和续期策略,并严格遵循安全规范。

相关文章:

  • Forking Workflow 详解
  • C语言基础知识10---栈、队列、树
  • leetcode 169.Majority Element
  • window离线全局安装yarn
  • 【Rtklib入门指南】4. 使用RTKLIB进行载波相位差分定位(RTK)
  • Scala(2)
  • QT学习day1
  • 计算机视觉——传统数字图像处理中图像去噪原理与代码实现细节
  • 全长约8.3公里!宁波象山港跨海大桥南中塔柱云端合龙
  • 十五届蓝桥杯省赛Java B组(持续更新..)
  • 蓝桥杯专项复习——二分
  • 《Fundamentals of Electromigration-Aware IntegratedCircuit Design》笔记
  • HTML中数字和字母不换行显示
  • 【C++游戏引擎开发】《线性代数》(5):四元数的3D旋转原理与实现(含新增Vector3、修改Matrix为非SIMD版本)
  • 【区块链安全 | 第十九篇】类型之映射类型
  • 【Node.js入门笔记12---npm包】
  • 聊聊Spring AI的RetrievalAugmentationAdvisor
  • Unity TextMeshPro 实现文本逐字淡出效果
  • 5.02 WPF的 Combox、ListBox,slider、ProgressBar使用
  • C语言--插入排序
  • 保定百度网站建设/站长工具seo查询软件
  • 做谱的网站/如何把网站推广出去
  • 哪些网站做的不好/下载百度极速版
  • 广东涂料网站建设/杭州seo的优化
  • 江阴做公司网站有哪些/seo网站平台
  • 单页网站建设服务好的商家/软文范例大全500字