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

JWT 过期后 自动刷新方案

JWT(JSON Web Token)广泛应用于现代 Web 开发中的认证与授权,它以无状态、灵活和高效的特点深受开发者欢迎。然而,JWT 的一个核心问题是 Token 过期后如何处理。本文将总结常见的解决方案,分析其优缺点,并帮助开发者选择适合自己项目的方案。


JWT 过期问题的挑战
  1. 安全性:如果 Token 长时间有效,泄露后可能导致严重的安全问题;短时间有效则需要频繁刷新。
  2. 无状态性:JWT 通常是无状态的,如何在不依赖后端存储的情况下管理过期 Token 成为难点。
  3. 刷新机制:如何设计高效、安全的 Token 刷新机制,避免用户频繁登录体验不佳。

解决方案

方案一:双 Token 模式(Access Token + Refresh Token)
设计思路
  • 使用两个 Token:
    1. Access Token:短生命周期(如 15 分钟)。
    2. Refresh Token:长生命周期(如 7 天)。
  • 客户端使用 Access Token 请求资源;当 Access Token 过期时,使用 Refresh Token 获取新的 Access Token 和 Refresh Token。
优点
  • 高安全性:Access Token 即使泄露,时间窗口较短,风险可控。
  • 客户端和服务器可以协同管理 Refresh Token,有效防止重复使用攻击。
缺点
  • 客户端实现复杂度较高,需要管理两个 Token。
  • 需要额外的接口和逻辑处理 Refresh Token。
适用场景
  • 对安全性要求较高的系统,如金融、支付平台。
核心代码

后端接口验证 Refresh Token 并生成新 Token:

@PostMapping("/refresh-token")
public ResponseEntity<?> refreshToken(@RequestBody Map<String, String> tokens) {String refreshToken = tokens.get("refreshToken");if (!jwtUtil.checkToken(refreshToken)) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid Refresh Token");}Map<String, String> claims = jwtUtil.decode(refreshToken);String newAccessToken = jwtUtil.generateJwtToken(claims.get("username"), claims.get("userId"));String newRefreshToken = jwtUtil.generateRefreshToken(claims.get("username"), claims.get("userId"));return ResponseEntity.ok(Map.of("accessToken", newAccessToken, "refreshToken", newRefreshToken));
}

方案二:固定 Session ID + Token
设计思路
  • 后端生成唯一的 Session ID 并与 Token 关联,将会话信息(如 Token 状态、用户信息)存储到 Redis 或数据库。
  • 客户端请求时,携带 Session ID 和 Token,后端验证会话状态和 Token。
优点
  • 可灵活控制会话状态,支持主动使某些 Session 失效。
  • 后端可以精细化管理 Token 状态,无需频繁解析 JWT 签名。
缺点
  • 依赖 Redis 或数据库存储会话信息,增加系统复杂度。
  • 不完全无状态,分布式部署时需要额外处理会话同步。
适用场景
  • 用户登录频繁、对会话状态要求高的系统。
核心代码
// 从 Redis 获取会话信息并验证 Token
SessionInfo sessionInfo = redisUtil.get("session_" + sessionId, SessionInfo.class);
if (sessionInfo == null || !sessionInfo.getToken().equals(token)) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Session Invalid");
}// Token 过期时刷新
if (jwtUtil.isTokenExpired(token)) {String newToken = jwtUtil.generateJwtToken(sessionInfo.getUsername(), sessionInfo.getUserId());sessionInfo.setToken(newToken);redisUtil.set("session_" + sessionId, sessionInfo);return ResponseEntity.ok(Map.of("newToken", newToken));
}

方案三:Token 无状态 + 客户端定时刷新
设计思路
  • Token 完全无状态,仅存储签名信息和过期时间。
  • 客户端定期检查 Token 的有效期,并在即将过期时主动请求刷新。
优点
  • 无需后端存储任何会话信息,完全无状态。
  • 简单高效,适合分布式系统。
缺点
  • 客户端需要管理 Token 刷新逻辑,增加复杂度。
  • 无法主动失效某个用户会话(如强制下线)。
适用场景
  • 轻量级或低安全需求的系统,如小型工具或内部系统。
核心代码

客户端定时检查并刷新:

function checkTokenExpiry() {const token = localStorage.getItem('accessToken');const payload = JSON.parse(atob(token.split('.')[1]));const expiryTime = payload.exp * 1000;if (Date.now() > expiryTime - 5 * 60 * 1000) { // 提前 5 分钟刷新refreshToken();}
}function refreshToken() {const refreshToken = localStorage.getItem('refreshToken');fetch('/refresh-token', {method: 'POST',body: JSON.stringify({ refreshToken }),headers: { 'Content-Type': 'application/json' }}).then(response => response.json()).then(data => {localStorage.setItem('accessToken', data.accessToken);localStorage.setItem('refreshToken', data.refreshToken);});
}

方案四:Hybrid Token(混合 Token)
设计思路
  • 将部分会话信息存储到 Token 中,而状态信息(如是否过期)存储在 Redis。
  • Token 验证时仅检查无状态部分,必要时从 Redis 获取状态信息。
优点
  • 兼顾无状态性和灵活性。
  • 后端可动态管理会话状态,同时减少频繁访问存储。
缺点
  • 实现较复杂,适合对性能要求较高的场景。
适用场景
  • 高并发、大规模分布式系统,如社交平台、内容分发系统。

方案对比

方案优点缺点适用场景
双 Token 模式高安全性;支持长生命周期管理增加客户端复杂度金融、支付等高安全系统
Session ID + Token灵活控制会话状态,支持主动失效依赖 Redis 或数据库存储登录频繁的系统
无状态 Token完全无状态,简单高效客户端复杂度高,无法主动失效内部工具、轻量级系统
Hybrid Token兼顾性能和灵活性实现复杂高并发分布式系统

结语

不同的方案适用于不同的场景,开发者在选择方案时需要考虑:

  1. 安全性:是否需要强安全性保障,如支持主动失效。
  2. 性能:是否需要减少后端存储依赖或高效处理。
  3. 复杂度:是否愿意增加客户端和后端的实现复杂性。

在实际开发中,可以结合业务需求和技术条件选择最适合的方案,甚至进行多方案组合,实现性能与安全的平衡。

相关文章:

JWT 过期后 自动刷新方案

JWT&#xff08;JSON Web Token&#xff09;广泛应用于现代 Web 开发中的认证与授权&#xff0c;它以无状态、灵活和高效的特点深受开发者欢迎。然而&#xff0c;JWT 的一个核心问题是 Token 过期后如何处理。本文将总结常见的解决方案&#xff0c;分析其优缺点&#xff0c;并帮…...

react-amap海量点优化

前言&#xff1a;高版本的react-amap 支持MassMarkers 组件用于一次性添加大量的标记点。本次优化的海量点是在低版本react-amap的基础上。官方推荐使用聚合useCluster属性来优化海量点的渲染。 直接附上代码&#xff1a; import React, { Component } from "react"…...

GRU(门控循环单元)详解

1️⃣ GRU介绍 前面介绍的LSTM可以有效缓解RNN的梯度消失问题&#xff0c;但是其内部结构比较复杂&#xff0c;因此衍生出了更加简化的GRU。GRU把输入门和遗忘门整合成一个更新门&#xff0c;并且合并了细胞状态和隐藏状态。于2014年被提出 2️⃣ 原理介绍 GRU的结构和最简单…...

【代码随想录|回溯算法排列问题】

491.非减子序列 题目链接. - 力扣&#xff08;LeetCode&#xff09; 这里和子集问题||很像&#xff0c;但是这里要的是非递减的子序列&#xff0c;要按照给的数组的顺序来进行排序&#xff0c;就是如果我给定的数组是[4,4,3,2,1]&#xff0c;如果用子集||的做法先进行排序得到…...

Azure Kubernetes Service (AKS)资源优化策略

针对Azure Kubernetes Service (AKS)的资源优化策略&#xff0c;可以从多个维度进行考虑和实施&#xff0c;以提升集群的性能、效率和资源利用率。以下是一些关键的优化策略&#xff1a; 一、 Pod资源请求和限制 设置Pod请求和限制&#xff1a;在YAML清单中为所有Pod设置CPU和…...

R语言 | 宽数据变成一列,保留对应的行名和列名

对应稀疏矩阵 转为 宽数据框&#xff0c;见 数据格式转换 | 稀疏矩阵3列还原为原始矩阵/数据框&#xff0c;自定义函数 df3toMatrix() 目的&#xff1a;比如查看鸢尾花整体的指标分布&#xff0c;4个指标分开&#xff0c;画到一个图中。每个品种画一个图。 1.数据整理&#…...

RTSP播放器EasyPlayer.js播放器在webview环境下,PC和安卓能够正常播放,IOS环境下播放器会黑屏无法播放

流媒体技术分为顺序流式传输和实时流式传输两种。顺序流式传输允许用户在下载的同时观看&#xff0c;而实时流式传输则允许用户实时观看内容。 流媒体播放器负责解码和呈现内容&#xff0c;常见的播放器包括VLC和HTML5播放器等。流媒体技术的应用场景广泛&#xff0c;包括娱乐…...

.NET周刊【11月第3期 2024-11-17】

国内文章 .NET 9使用Scalar替代Swagger https://www.cnblogs.com/netry/p/18543378/scalar-an-alternative-to-swagger-in-dotnet-9 .NET 9 移除了 Swashbuckle.AspNetCore&#xff0c;因为其维护不力&#xff0c;并转向 Microsoft.AspNetCore.OpenApi。除了 Swashbuckle&am…...

c语言数据22数组使用

1.1数组分配的空间 int a[10]{1,2,3,4,5,6,7,8,9,10};//分配空间 元素类型大小int4*元素个数1040byte 元素之间空间连续 数组名代表数组首元素地址&#xff1b;a 取的是a[0]的地址&#xff1b;&a 是整个数组的地址 说明&#xff1a; 数组首元素地址&#xff1a; 0号元…...

深入理解TensorFlow中的形状处理函数

摘要 在深度学习模型的构建过程中&#xff0c;张量&#xff08;Tensor&#xff09;的形状管理是一项至关重要的任务。特别是在使用TensorFlow等框架时&#xff0c;确保张量的形状符合预期是保证模型正确运行的基础。本文将详细介绍几个常用的形状处理函数&#xff0c;包括get_…...

MySQL数据库3——函数与约束

一.函数 1.字符串函数 MySQL中内置了很多字符串函数&#xff0c;常用的几个如下&#xff1a; 使用方法&#xff1a; SELECT 函数名(参数);注意&#xff1a;MySQL中的索引值即下标都是从1开始的。 2.数值函数 常见的数值函数如下&#xff1a; 使用方法&#xff1a; SELECT…...

⾃动化运维利器 Ansible-Jinja2

Ansible-Jinja2 一、Ansible Jinja2模板背景介绍二、 JinJa2 模板2.1 JinJa2 是什么2.2 JinJa2逻辑控制 三、如何使用模板四、实例演示 按顺序食用&#xff0c;口味更佳 ( 1 ) ⾃动化运维利器Ansible-基础 ( 2 ) ⾃动化运维利器 Ansible-Playbook ( 3 ) ⾃动化运维利器 Ansible…...

博客文章怎么设计分类与标签

首发地址&#xff08;欢迎大家访问&#xff09;&#xff1a;博客文章怎么设计分类与标签 新网站基本上算是迁移完了&#xff0c;迁移之后在写文章的过程中&#xff0c;发现个人的文章分类和标签做的太混乱了&#xff0c;分类做的像标签&#xff0c;标签也不是特别的丰富&#x…...

FastDDS之DataSharing

目录 原理说明限制条件配置Data-Sharing delivery kindData-sharing domain identifiers最大domain identifiers数量共享内存目录 DataReader和DataWriter的history耦合DataAck阻塞复用 本文详细记录Fast DDS中Data Sharing的实现原理和代码分析。 DataSharing的概念&#xff1…...

计算机网络在线测试-概述

单项选择题 第1题 数据通信中&#xff0c;数据传输速率&#xff08;比特率&#xff0c;bps&#xff09;是指每秒钟发送的&#xff08;&#xff09;。 二进制位数 &#xff08;我的答案&#xff09; 符号数 字节数 码元数 第2题 一座大楼内的一个计算机网络系统&#xf…...

【MySQL】数据库必考知识点:查询操作全面详解与深度解剖

前言&#xff1a;本节内容讲述基本查询&#xff0c; 基本查询要分为两篇文章进行讲解。 本篇文章主要讲解的是表内删除数据、查询结果进行插入、聚合统计、分组聚合统计。 如果想要学习对应知识的可以观看哦。 ps:本篇内容友友们只要会创建表了就可以看起来了哦&#xff01;&am…...

鲸鱼机器人和乐高机器人的比较

鲸鱼机器人和乐高机器人各有其独特的优势和特点&#xff0c;家长在选择时可以根据孩子的年龄、兴趣、经济能力等因素进行综合考虑&#xff0c;选择最适合孩子的教育机器人产品。 优势 鲸鱼机器人 1&#xff09;价格亲民&#xff1a;鲸鱼机器人的产品价格相对乐高更为亲民&…...

游戏引擎学习第15天

视频参考:https://www.bilibili.com/video/BV1mbUBY7E24 关于游戏中文件输入输出&#xff08;IO&#xff09;操作的讨论。主要分为两类&#xff1a; 只读资产的加载 这部分主要涉及游戏中用于展示和运行的只读资源&#xff0c;例如音乐、音效、美术资源&#xff08;如 3D 模型和…...

详解模版类pair

目录 一、pair简介 二、 pair的创建 三、pair的赋值 四、pair的排序 &#xff08;1&#xff09;用sort默认排序 &#xff08;2&#xff09;用sort中的自定义排序进行排序 五、pair的交换操作 一、pair简介 pair是一个模版类&#xff0c;可以存储两个值的键值对.first以…...

AI驱动的桌面笔记应用Reor

网友 竹林风 说&#xff0c;已经成功的用 mxbai-embed-large 映射到 text-embedding-ada-002&#xff0c;并测试成功了。不愧是爱折腾的人&#xff0c;老苏还没时间试&#xff0c;因为又找到了另一个支持 AI 的桌面版笔记 Reor Reor 简介 什么是 Reor ? Reor 是一款由人工智…...

Open SWE 生态层:SWE-bench 基准测试与模型选型指南

Open SWE 生态层&#xff1a;SWE-bench 基准测试与模型选型指南在评估 AI 编码智能体时&#xff0c;基准测试是衡量能力的重要标尺。SWE-bench 是当前最具权威性的软件工程基准测试&#xff0c;Open SWE 支持多种模型运行。本文将深入解析 SWE-bench 体系&#xff0c;并提供实用…...

OpenClaw长任务管理:Qwen3-VL:30B连续执行优化

OpenClaw长任务管理&#xff1a;Qwen3-VL:30B连续执行优化 1. 长任务管理的痛点与挑战 上周我尝试用OpenClaw自动化处理一个复杂的市场分析报告生成任务。这个任务需要连续执行网页搜索、数据提取、图表生成和报告撰写四个步骤&#xff0c;预计耗时约40分钟。然而在第三次运行…...

Coze智能客服部署指南:从零搭建到生产环境最佳实践

最近在折腾智能客服系统的部署&#xff0c;发现市面上虽然方案不少&#xff0c;但真正能兼顾快速落地、稳定运行和成本可控的并不多。Coze 作为一个新兴的选项&#xff0c;以其灵活的架构和不错的性能吸引了我。经过一番从零到生产环境的摸索&#xff0c;我总结了一套部署指南&…...

基于ChatTTS .pt模型的AI辅助开发实战:从语音合成到生产环境部署

最近在做一个需要语音合成的项目&#xff0c;之前用了一些开源的TTS方案&#xff0c;总感觉差点意思&#xff1a;要么生成一句话要等好几秒&#xff0c;急死人&#xff1b;要么合成的语音听起来很“机械”&#xff0c;没有真人说话的那种起伏和情感&#xff1b;想支持点方言或者…...

R语言实战:单因素方差分析从数据导入到结果解读(附完整代码)

R语言实战&#xff1a;单因素方差分析从数据导入到结果解读&#xff08;附完整代码&#xff09; 当你第一次面对一组实验数据&#xff0c;试图比较不同处理组间的差异时&#xff0c;单因素方差分析&#xff08;One-way ANOVA&#xff09;往往是首选方法。作为R语言数据分析的基…...

Face Analysis WebUI在AR眼镜中的应用:实时身份识别

Face Analysis WebUI在AR眼镜中的应用&#xff1a;实时身份识别 1. 引言 想象一下&#xff0c;当你戴着AR眼镜走在街上&#xff0c;迎面走来一位同事&#xff0c;眼镜瞬间识别出他的身份并在视野角落显示姓名和职位信息。或者进入会议室&#xff0c;AR眼镜自动识别所有参会人…...

ROS2与Python的完美结合:手把手教你创建第一个功能包

ROS2与Python的完美结合&#xff1a;手把手教你创建第一个功能包 在机器人开发领域&#xff0c;ROS2已经成为事实上的标准框架&#xff0c;而Python凭借其简洁易用的特性&#xff0c;成为快速原型开发的首选语言。当这两者相遇&#xff0c;会擦出怎样的火花&#xff1f;本文将带…...

刷题党必备:用Python实现《代码随想录》12大算法模板(含二叉树/回溯/DP)

Python算法实战&#xff1a;12大核心模板精解与LeetCode百题斩 在技术面试中&#xff0c;算法能力往往是区分普通开发者与顶尖工程师的关键指标。无论是硅谷科技巨头还是国内一线互联网公司&#xff0c;算法题已成为筛选候选人的标配环节。本文将系统性地介绍12类高频算法模板&…...

Legado阅读器内置Web服务器技术深度解析:NanoHTTPD在Android嵌入式环境中的架构设计与性能优化

Legado阅读器内置Web服务器技术深度解析&#xff1a;NanoHTTPD在Android嵌入式环境中的架构设计与性能优化 【免费下载链接】legado Legado 3.0 Book Reader with powerful controls & full functions❤️阅读3.0, 阅读是一款可以自定义来源阅读网络内容的工具&#xff0c;…...

B站成分检测器:5分钟掌握评论区用户画像分析终极指南

B站成分检测器&#xff1a;5分钟掌握评论区用户画像分析终极指南 【免费下载链接】bilibili-comment-checker B站评论区自动标注成分&#xff0c;支持动态和关注识别以及手动输入 UID 识别 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-comment-checker 在B站…...