Token快过期的三种续期方案 - 详解

news/2025/11/18 21:33:49/文章来源:https://www.cnblogs.com/ljbguanli/p/19239342

Token快过期的三种续期方案 - 详解

目录

滑动窗口机制 (Sliding Window Mechanism)

核心原理:

方案实现流程:

Java代码实现:

优点:

缺点:

双Token机制/刷新令牌机制(Refresh Token)

核心原理:

方案实现流程:

Java代码实现:

优点:

缺点:

服务端自动续期

核心原理:

方案实现流程:

Java代码实现:

优点:

缺点:

总结对比


用于实现Token续期的三大主流方案:滑动窗口机制、双Token/刷新令牌机制 (Refresh Token) 和 服务端自动续期。

滑动窗口机制 (Sliding Window Mechanism)

核心原理:

只要用户的Token在有效期内有活动,就会自动延长其Token过期时间

方案实现流程:

  1. 用户发起请求的时候携带Token,后端校验Token的有效性及剩余时间
  2. Token有效并且剩余时间低于阈值,后端生成新的Token(延长过期时间)
  3. 返回响应数据和新的Token给前端,前端使用新的Token替换旧的Token
  4. 若Token有效并且剩余时间高于阈值,返回正常响应数据,更换Token

Java代码实现:

@RestController
@Slf4j
public class AuthController {/*** Token过期时间(毫秒)*/private static final long ACCESS_TOKEN_EXPIRATION_TIME = 30 * 60 * 1000; // 30分钟/*** 续期阈值(毫秒)*/private static final long RENEWAL_THRESHOLD = 5 * 60 * 1000; // 5分钟内触发续期/*** 密钥*/private static final String SECRET = "PXrQbuCwXwOZzkML/Vm2S5rSwt1iybvmKtGDzVEu+Hc=";/*** 检查并续期Token* 如果传入的Token即将过期(剩余时间小于等于续期阈值),则生成一个新的Token返回;* 否则返回成功的响应,表示Token仍然有效。** @param token 请求头中的Authorization字段,即原始Token* @return Result 响应结果,若需要续期则返回新的Token,否则返回空的成功结果*/@GetMapping("/api/token")public Result register(@RequestHeader("Authorization") String token) {//1. 基础校验if (token == null) {return Result.error(ResultCode.UNAUTHORIZED); // 401 未授权}//2. 验证tokenAlgorithm algorithm = Algorithm.HMAC256(SECRET);DecodedJWT decodedJWT = JWT.require(algorithm).build().verify(token);Date expirationDate = decodedJWT.getExpiresAt();long currentTime = System.currentTimeMillis();long timeUntilExpiry = expirationDate.getTime() - currentTime;// 判断是否需要续期:当剩余有效时间小于等于设定阈值时if (timeUntilExpiry <= RENEWAL_THRESHOLD) {// 生成新的TokenString newToken = generateToken(decodedJWT.getClaim("userId").asString());return Result.success(newToken);}return Result.success();}/*** 根据用户ID生成新的JWT Token** @param userId 用户唯一标识* @return 新生成的JWT Token字符串*/private String generateToken(String userId) {Date now = new Date();Date expirationDate = new Date(now.getTime() + ACCESS_TOKEN_EXPIRATION_TIME); // 过期时间为30分钟return JWT.create().withIssuer("your_issuer").withIssuedAt(now).withExpiresAt(expirationDate).withClaim("userId", userId).sign(Algorithm.HMAC256(SECRET));}
}

优点:

  • 用户体验佳:用户在持续操作的时候,完全感知不到登录状态的中断,体验非常流畅。
  • 实现相对简单:逻辑清晰,代码改动小,易于集成到现有系统中。

缺点:

  • 安全性低:如果用户的Token被窃取,攻击者只要持续发起请求,就可以让这个Token“永不过期”,大大增加了被滥用的风险。
  • 难以控制最大会话时长:虽然每次都在续期,但很难限制一个会话的绝对最大生命周期(比如用户登录后必须24小时后强制重新登录)。

双Token机制/刷新令牌机制(Refresh Token)

此方案为业界最为主流、最推荐的方案,安全性高

核心原理:

此方案引入两种不同生命周期的Token

  • Access Token (访问令牌):
    • 生命周期短,一般为15分钟-2小时
    • 每次请求API的时候都会带在Authorization头中
    • 包含用户部分身份信息,用于快速校验
  • Refresh Token (刷新令牌):
    • 生命周期长,一般7天-30天
    • 不用于访问API,仅用于获取新的Access Token。
    • 需要搭配服务端的Redis进行使用,用于校验其有效性。

方案实现流程:

  1. 用户发起登录请求,后端校验用户相关信息,若成功,后端生成Access Token和Refresh Token返回给前端,并且将Refresh Token存储到redis中用于后续的校验
  2. 用户再次请求服务端的时候,用户需要携带Access Token,若后端校验成功,那么成功响应或者继续处理;后端校验失败,返回401
  3. 用户端携带Refresh Token调用refresh接口,验证Refresh Token有效性及匹配性
  4. Refresh Token有效并且匹配,后端生成新的Access Token和新的Refresh Token,删除旧的Refresh Token,并且存储新的Refresh Token;后端执行成功,返回新的Access Token 和Refresh Token;若Refresh Token无效,则返回错误信息
  5. 后续用户端请求的时候使用新的Access Token重新发起之前失败的请求

Java代码实现:

  • 注意:此处的代码是经过业务封装后的代码,大家关注业务逻辑即可,不必关注详细的实现细节
@RestController
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/api/v1/auth")
public class AuthController {private final JwtUtil jwtUtil; // jwt实现类/*** 刷新refreshToken** @param refreshTokenRequest refreshToken* @return refreshTokenResponse*/@GetMapping("/refreshToken")public Result refreshToken(@RequestBody @Valid RefreshTokenRequest refreshTokenRequest) {log.info("刷新token, refreshToken:{}",refreshTokenRequest.getRefreshToken());if (refreshTokenRequest.getRefreshToken() == null || refreshTokenRequest.getRefreshToken().isEmpty()){log.info("refreshToken为空或者不存在");return Result.error(ResultCode.UNAUTHORIZED);}//1. 从refreshToken中获取用户名String username = jwtUtil.extractUsernameFromToken(refreshTokenRequest.getRefreshToken());if (username == null || username.isEmpty()){log.info("refreshToken无效,此处无法提取出用户名");return Result.error(ResultCode.TOKEN_INVALID);}//3. 校验refreshTokenif (!jwtUtil.validateRefreshToken(refreshTokenRequest.getRefreshToken())){log.info("校验refreshToken失败:refreshToken{}", refreshTokenRequest.getRefreshToken());return Result.error(ResultCode.UNAUTHORIZED);}//4. 重新生成token和refreshTokenString newToken = jwtUtil.generateToken(username);String newRefreshToken = jwtUtil.generateRefreshToken(username);log.info("刷新token成功,newToken:{}, newRefreshToken:{}", newToken, newRefreshToken);return Result.success(RefreshTokenResponse.builder().token(newToken).refreshToken(newRefreshToken).build());}
}

优点:

  • 高安全性:Access Token 寿命比较短,即使暴露危害相对较小
  • 灵活性高:可以精确控制 Access TokenRefresh Token 的生命周期。

缺点:

  • 实现复杂度高:需要管理两种Token,需要额外的存储(如Redis)来维护 Refresh Token 的状态。
  • 增加网络请求:Access Token 过期时,需要先请求一次刷新接口,再重试原请求。

服务端自动续期

核心原理:

此方案和滑动窗口方案有类似之处,但是此方案更侧重于服务端主动管理和维护会话状态。并且此处的服务端自动续期是有状态的,依赖redis等存储来维护会话。然而滑动窗口方案是无状态的,只需要依赖Token本身即可。

方案实现流程:

Java代码实现:

优点:

  • 控制力强:管理员可以完全掌控所有会话的状态。
  • 安全性相对较高:可以实现强制下线、多端登录限制等功能。
  • 可审计:所有会话活动都有记录。

缺点:

  • 性能开销大:每次请求都需要查询和更新Redis,对数据库压力大。
  • 系统复杂性高:需要维护会话存储和清理机制。
  • 违背JWT无状态原则:JWT的设计初衷是无状态,此方案使其变为有状态,失去了部分优势。

总结对比

特性

滑动窗口机制

双Token/刷新令牌

服务端自动续期

用户体验

⭐⭐⭐⭐⭐ (最佳)

⭐⭐⭐⭐ (良好)

⭐⭐⭐⭐ (良好)

安全性

⭐⭐ (较低)

⭐⭐⭐⭐⭐ (最高)

⭐⭐⭐⭐ (高)

实现复杂度

⭐⭐ (简单)

⭐⭐⭐⭐ (复杂)

⭐⭐⭐⭐⭐ (最复杂)

服务器开销

⭐⭐⭐ (中等)

⭐⭐⭐ (中等)

⭐⭐ (高)

是否无状态

否 (Refresh Token需存储)

主流推荐度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/969367.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重组蛋白科研试剂技术综述:结构特性、功能机制与实验体系应用

重组蛋白作为生命科学研究的核心科研试剂,已成为现代实验体系中不可或缺的基础材料。它们通过基因工程技术表达、纯化而成,具有结构明确、批次稳定、功能可控等特点,使科研人员能够在体外模拟体内信号环境,研究细胞…

linux c 命令

当然可以!你提到的是“Linux C 命令”,这可能是指在 Linux 系统中使用 C 语言编写的命令或脚本,或者是使用 C 语言进行系统调用、进程管理、文件操作等。以下是一些常见的 Linux C 命令和相关功能的解释,帮助你更好…

日总结 28

Java C/S 架构的开发与打包为.exe: 一、Java C/S 架构开发核心 架构拆分 客户端:负责 UI 交互(Swing/JavaFX)、本地逻辑处理、网络请求发送。 服务器端:处理核心业务逻辑(Spring Boot/Netty)、数据存储(MySQL/…

游戏联运模式与统一包模式

游戏联运模式与统一包模式是移动游戏发行中两种常见的分发和合作方式,它们在合作机制、技术实现、收益分配、运营控制等方面存在显著差异。 下面是对这两种模式的详细对比: 一、游戏联运模式(联合运营) 1. 定义 联…

游戏统一包模式下活动营销系统后续的发展方向

在游戏统一包模式(即使用单一官方安装包、不依赖传统联运渠道SDK)日益普及的背景下,渠道侧的活动营销系统正面临深刻转型。虽然统一包削弱了渠道对用户账号、支付和数据的直接控制,但渠道仍可通过新的方式参与游戏…

taptap以官包模式下如何开展营销活动

在 TapTap 以官包(官方包)模式 下开展营销活动,是当前许多重视用户资产、追求高毛利和品牌自主权的游戏厂商(如米哈游、鹰角、库洛等)的首选策略。TapTap 本身定位为“不联运、不分成、去渠道化”的游戏分发与社区…

实用指南:AI: 生成Android自我学习路线规划与实战

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Jupyter/IPython 魔法命令列表

Jupyter/IPython 魔法命令列表安装依赖命令# 性能分析工具 %pip install line_profiler %pip install memory_profiler# 加载扩展 %load_ext line_profiler %load_ext memory_profiler常用组合# 性能测试组合 %timeit …

《算法设计与分析》第三章学习记录

1.按照动态规划法的求解步骤分析作业题目“数字三角形”: 1.1设a[][]=三角形第i行第j列的值(0<=i<n,0<=j<=i) 定义:dp[i][j]=从(i,j)出发到底边的最大路径和 递归方程式:dp[i][j] = a[i][j] + max(dp[i…

第29天(中等题 二分查找)

打卡第二十九天 2道中等题题目:思路:二分查找 代码: class Solution { public:int smallestDivisor(vector<int>& nums, int threshold) {auto check = [&] (int m) -> bool{int sum = 0;for(int x :…

#题解#洛谷 P3029 Cow Lineup S #双指针#离散化#

P3029 [USACO11NOV] Cow Lineup S - 洛谷 分析离散化,双指针代码实现 #include<bits/stdc++.h> using namespace std; const int N = 1e5+10; struct cow {int pos, x; } a[N]; bool cmp(cow x, cow y) {return…

题解:AtCoder ARC192D Fraction Line

一些记号 下文中令 \(d_p(x)=\max\limits_{k\in\mathbb{N},p^k\mid x}k\)。 题意 对于 \(x\in\mathbb{Q}^{+}\),设 \(x=\dfrac{p}{q}\),其中 \(p,q\) 为互质正整数,令 \(f(x)=pq\)。给定长度为 \(n-1\) 的序列 \(a\…

Linux如何安装利用Rust指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

tryhackme-网络安全基础-网络- 网络概念-24

tryhackme-Cyber Security 101-Networking-Networking Concepts 房间地址:https://tryhackme.com/room/networkingconcepts 这是网络安全入门的基础模块的计算机科学基础知识:网络概念,序号 01 表示第一篇文章,当你…

省赛前记不住的数学知识

裴蜀定理 对于 \(S=\sum\limits_{i=1}^{n}a_ix_i\) 有解的充要条件为 \(\gcd(a_1,a_2,\cdots,a_n)\mid S\)。 拉格朗日插值 \[f(x)=\sum_i\big( \prod_{j\ne i}\dfrac{x-x_j}{x_i-x_j}\big)y_i \]扩展欧拉定理 \[a^b \…

如何创建你的百Google度!!(实现双搜索引擎页面)

创建双搜索引擎页面 百Google度的网站被封了,但!!!这不影响我们创建属于自己的双搜索引擎页面! 提前准备 找到你想添加的俩个搜索引擎对应的URI 和 它预先定义用于存储搜索关键词的参数名。打开你想要的搜索引擎的…

P7152 [USACO20DEC] Bovine Genetics G

首先有一个 \(O(n^2)\) 的 dp。 设计状态 \(f_{i,0/1/2/3}\) 表示前 \(i\) 个字符以 \(A,C,G,T\) 中哪一个结尾的方案数。 \(f_{i,x}=\sum_j \sum_y f_{j,y}w(i,j,x,y)\)

如何在ISA-95体系中采用Apache Camel + MQTT Broker衔接L3与L4 Legacy应用

如何在ISA-95体系中采用Apache Camel + MQTT Broker衔接L3与L4 Legacy应用2025-11-18 21:07 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: …

11月18日日记

1.今天上工程实训课做方形盒子 2.明天学习马哲 3.Tomcat 10 与 Tomcat 9 的核心区别?Servlet API 版本如何适配?

一文讲清:数据清洗、数据中台、数据仓库、数据治理 - 智慧园区

你有没有遇到过这种情况?业务部门急着要一份数据报告,IT同事折腾了好几天,最后告诉你数据对不上,或者根本取不出来。 公司开会,两个部门拿着同一项业务指标的数据争论不休,因为大家手里的数字根本不一样。 想上线…