JWT 过期后 自动刷新方案
JWT(JSON Web Token)广泛应用于现代 Web 开发中的认证与授权,它以无状态、灵活和高效的特点深受开发者欢迎。然而,JWT 的一个核心问题是 Token 过期后如何处理。本文将总结常见的解决方案,分析其优缺点,并帮助开发者选择适合自己项目的方案。
JWT 过期问题的挑战
- 安全性:如果 Token 长时间有效,泄露后可能导致严重的安全问题;短时间有效则需要频繁刷新。
- 无状态性:JWT 通常是无状态的,如何在不依赖后端存储的情况下管理过期 Token 成为难点。
- 刷新机制:如何设计高效、安全的 Token 刷新机制,避免用户频繁登录体验不佳。
解决方案
方案一:双 Token 模式(Access Token + Refresh Token)
设计思路
- 使用两个 Token:
- Access Token:短生命周期(如 15 分钟)。
- 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 | 兼顾性能和灵活性 | 实现复杂 | 高并发分布式系统 |
结语
不同的方案适用于不同的场景,开发者在选择方案时需要考虑:
- 安全性:是否需要强安全性保障,如支持主动失效。
- 性能:是否需要减少后端存储依赖或高效处理。
- 复杂度:是否愿意增加客户端和后端的实现复杂性。
在实际开发中,可以结合业务需求和技术条件选择最适合的方案,甚至进行多方案组合,实现性能与安全的平衡。
相关文章:
JWT 过期后 自动刷新方案
JWT(JSON Web Token)广泛应用于现代 Web 开发中的认证与授权,它以无状态、灵活和高效的特点深受开发者欢迎。然而,JWT 的一个核心问题是 Token 过期后如何处理。本文将总结常见的解决方案,分析其优缺点,并帮…...
react-amap海量点优化
前言:高版本的react-amap 支持MassMarkers 组件用于一次性添加大量的标记点。本次优化的海量点是在低版本react-amap的基础上。官方推荐使用聚合useCluster属性来优化海量点的渲染。 直接附上代码: import React, { Component } from "react"…...

GRU(门控循环单元)详解
1️⃣ GRU介绍 前面介绍的LSTM可以有效缓解RNN的梯度消失问题,但是其内部结构比较复杂,因此衍生出了更加简化的GRU。GRU把输入门和遗忘门整合成一个更新门,并且合并了细胞状态和隐藏状态。于2014年被提出 2️⃣ 原理介绍 GRU的结构和最简单…...
【代码随想录|回溯算法排列问题】
491.非减子序列 题目链接. - 力扣(LeetCode) 这里和子集问题||很像,但是这里要的是非递减的子序列,要按照给的数组的顺序来进行排序,就是如果我给定的数组是[4,4,3,2,1],如果用子集||的做法先进行排序得到…...

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

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

RTSP播放器EasyPlayer.js播放器在webview环境下,PC和安卓能够正常播放,IOS环境下播放器会黑屏无法播放
流媒体技术分为顺序流式传输和实时流式传输两种。顺序流式传输允许用户在下载的同时观看,而实时流式传输则允许用户实时观看内容。 流媒体播放器负责解码和呈现内容,常见的播放器包括VLC和HTML5播放器等。流媒体技术的应用场景广泛,包括娱乐…...
.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,因为其维护不力,并转向 Microsoft.AspNetCore.OpenApi。除了 Swashbuckle&am…...
c语言数据22数组使用
1.1数组分配的空间 int a[10]{1,2,3,4,5,6,7,8,9,10};//分配空间 元素类型大小int4*元素个数1040byte 元素之间空间连续 数组名代表数组首元素地址;a 取的是a[0]的地址;&a 是整个数组的地址 说明: 数组首元素地址: 0号元…...
深入理解TensorFlow中的形状处理函数
摘要 在深度学习模型的构建过程中,张量(Tensor)的形状管理是一项至关重要的任务。特别是在使用TensorFlow等框架时,确保张量的形状符合预期是保证模型正确运行的基础。本文将详细介绍几个常用的形状处理函数,包括get_…...

MySQL数据库3——函数与约束
一.函数 1.字符串函数 MySQL中内置了很多字符串函数,常用的几个如下: 使用方法: SELECT 函数名(参数);注意:MySQL中的索引值即下标都是从1开始的。 2.数值函数 常见的数值函数如下: 使用方法: SELECT…...
⾃动化运维利器 Ansible-Jinja2
Ansible-Jinja2 一、Ansible Jinja2模板背景介绍二、 JinJa2 模板2.1 JinJa2 是什么2.2 JinJa2逻辑控制 三、如何使用模板四、实例演示 按顺序食用,口味更佳 ( 1 ) ⾃动化运维利器Ansible-基础 ( 2 ) ⾃动化运维利器 Ansible-Playbook ( 3 ) ⾃动化运维利器 Ansible…...

博客文章怎么设计分类与标签
首发地址(欢迎大家访问):博客文章怎么设计分类与标签 新网站基本上算是迁移完了,迁移之后在写文章的过程中,发现个人的文章分类和标签做的太混乱了,分类做的像标签,标签也不是特别的丰富&#x…...
FastDDS之DataSharing
目录 原理说明限制条件配置Data-Sharing delivery kindData-sharing domain identifiers最大domain identifiers数量共享内存目录 DataReader和DataWriter的history耦合DataAck阻塞复用 本文详细记录Fast DDS中Data Sharing的实现原理和代码分析。 DataSharing的概念࿱…...
计算机网络在线测试-概述
单项选择题 第1题 数据通信中,数据传输速率(比特率,bps)是指每秒钟发送的()。 二进制位数 (我的答案) 符号数 字节数 码元数 第2题 一座大楼内的一个计算机网络系统…...

【MySQL】数据库必考知识点:查询操作全面详解与深度解剖
前言:本节内容讲述基本查询, 基本查询要分为两篇文章进行讲解。 本篇文章主要讲解的是表内删除数据、查询结果进行插入、聚合统计、分组聚合统计。 如果想要学习对应知识的可以观看哦。 ps:本篇内容友友们只要会创建表了就可以看起来了哦!&am…...

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

游戏引擎学习第15天
视频参考:https://www.bilibili.com/video/BV1mbUBY7E24 关于游戏中文件输入输出(IO)操作的讨论。主要分为两类: 只读资产的加载 这部分主要涉及游戏中用于展示和运行的只读资源,例如音乐、音效、美术资源(如 3D 模型和…...

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

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

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...