Sa-Token的Token有效期和临时有效期的区别

2023-11-04

各位不要再卷了。周六我在家打着游戏,群消息就一直叮叮叮,进去看了看 ,周六还加班干活。哎真卷。(ps:在卷就没了,吐槽一下)

        进入正题,就周六群友提问做一下总结,群友问题,为什么

 不能续期,先说一下这位群友的测试方法,token有效期 10秒 ,在登陆后等待Token到期,在调用 renewTimeout 方法,很不幸 ,这个方法是错误的。 原因呢?很明显。这位群友使用了redis,集成了sa-token-redis包,那么 token的有效期就变成了redis-key的TTL(免得你们百度,直接说了TTL为当前key的生命周期) ,当token到期后 ,会被清空掉,所以renewTimeout方法也就失效了,详细的看一下源码


 	/**
 	 * 对当前 Token 的 timeout 值进行续期 
 	 * @param timeout 要修改成为的有效时间 (单位: 秒) 
 	 */
 	public void renewTimeout(long timeout) {
 		// 续期 db 数据 
 		String tokenValue = getTokenValue();
 		renewTimeout(tokenValue, timeout);
 		
 		// 续期客户端Cookie有效期 
 		if(getConfig().getIsReadCookie()) {
 			setTokenValueToCookie(tokenValue, (int)timeout);
 		}
 	}



 	/**
 	 * 对指定 Token 的 timeout 值进行续期 
 	 * @param tokenValue 指定token 
 	 * @param timeout 要修改成为的有效时间 (单位: 秒) 
 	 */
 	public void renewTimeout(String tokenValue, long timeout) {
 		
 		// Token 指向的 LoginId 异常时,不进行任何操作 
 		Object loginId = getLoginIdByToken(tokenValue);
 		if(loginId == null) {
 			return;
 		}
 		
 		SaTokenDao dao = getSaTokenDao();
 		
 		// 续期 Token 有效期 
 		dao.updateTimeout(splicingKeyTokenValue(tokenValue), timeout);

 		// 续期 Token-Session 有效期 
		SaSession tokenSession = getTokenSessionByToken(tokenValue, false);
		if(tokenSession != null) {
			tokenSession.updateTimeout(timeout);
		}
		
 		// 续期指向的 User-Session 有效期 
 		getSessionByLoginId(loginId).updateMinTimeout(timeout);
 		
 		// Token-Activity 活跃检查相关 
 		if(isOpenActivityCheck()) {
 			dao.updateTimeout(splicingKeyLastActivityTime(tokenValue), timeout);
 		}
 	}


    
	/**
	 * 修改Value的剩余存活时间 (单位: 秒) 
	 */
	@Override
	public void updateTimeout(String key, long timeout) {
		// 判断是否想要设置为永久
		if(timeout == SaTokenDao.NEVER_EXPIRE) {
			long expire = getTimeout(key);
			if(expire == SaTokenDao.NEVER_EXPIRE) {
				// 如果其已经被设置为永久,则不作任何处理 
			} else {
				// 如果尚未被设置为永久,那么再次set一次
				this.set(key, this.get(key), timeout);
			}
			return;
		}
		stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);
	}

这三个方法很清楚的写出了renewTimeout的逻辑,就是重新修改当前key的TTL。到此群友问题解决。
        下面再说说和TokenTime看似一样,实际天差地别的东西,activity-timeout(token临时有效期),其实也很好理解,指定时间内无操作就视为token过期,前面说到Token的有效期是redis-key的TTL,而activity-timeout逻辑则是在Session中记录最后操作时间,在判断时根据最后操作时间以及当前时间做差,然后和配置文件中配置的activity-timeout在做差,得出是否过期,下面上代码


 	/**
 	 * 获取指定 token [临时过期] 剩余有效时间 (单位: 秒)
 	 * @param tokenValue 指定token 
 	 * @return token[临时过期]剩余有效时间
 	 */
 	public long getTokenActivityTimeoutByToken(String tokenValue) {
 		// 如果token为null , 则返回 -2
 		if(tokenValue == null) {
 			return SaTokenDao.NOT_VALUE_EXPIRE;
 		}
 		// 如果设置了永不过期, 则返回 -1 
 		if(isOpenActivityCheck() == false) {
 			return SaTokenDao.NEVER_EXPIRE;
 		}
 		// ------ 开始查询 
 		// 获取相关数据 
 		String keyLastActivityTime = splicingKeyLastActivityTime(tokenValue);
 		String lastActivityTimeString = getSaTokenDao().get(keyLastActivityTime);
 		// 查不到,返回-2 
 		if(lastActivityTimeString == null) {
 			return SaTokenDao.NOT_VALUE_EXPIRE;
 		}
 		// 计算相差时间
 		long lastActivityTime = Long.parseLong(lastActivityTimeString);
 		long apartSecond = (System.currentTimeMillis() - lastActivityTime) / 1000;
 		long timeout = getConfig().getActivityTimeout() - apartSecond;
 		// 如果 < 0, 代表已经过期 ,返回-2 
 		if(timeout < 0) {
 			return SaTokenDao.NOT_VALUE_EXPIRE;
 		}
 		return timeout;
 	}

通过上面的代码,就可以清晰的看出activity-timeout的处理逻辑。

各位如果觉得有用得上的地方,就点个赞吧,如果有不同的看法,可以在评论里面反馈。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Sa-Token的Token有效期和临时有效期的区别 的相关文章

  • Grails 3.x bootRun 失败

    我正在尝试在 grails 3 1 11 中运行一个项目 但出现错误 失败 构建失败并出现异常 什么地方出了错 任务 bootRun 执行失败 进程 命令 C Program Files Java jdk1 8 0 111 bin java
  • Java new Date() 打印

    刚刚学习 Java 我知道这可能听起来很愚蠢 但我不得不问 System out print new Date 我知道参数中的任何内容都会转换为字符串 最终值是 new Date 返回对 Date 对象的引用 那么它是如何打印这个的呢 Mo
  • 如何使用 Java 和 Selenium WebDriver 在 C 目录中创建文件夹并需要将屏幕截图保存在该目录中?

    目前正在与硒网络驱动程序和代码Java 我有一种情况 我需要在 C 目录中创建一个文件夹 并在该文件夹中创建我通过 selenium Web 驱动程序代码拍摄的屏幕截图 它需要存储在带有时间戳的文件夹中 如果我每天按计划运行脚本 所有屏幕截
  • Spring Batch 多线程 - 如何使每个线程读取唯一的记录?

    这个问题在很多论坛上都被问过很多次了 但我没有看到适合我的答案 我正在尝试在我的 Spring Batch 实现中实现多线程步骤 有一个包含 100k 条记录的临时表 想要在 10 个线程中处理它 每个线程的提交间隔为 300 因此在任何时
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • Java - 将节点添加到列表的末尾?

    这是我所拥有的 public class Node Object data Node next Node Object data Node next this data data this next next public Object g
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • Spark 1.3.1 上的 Apache Phoenix(4.3.1 和 4.4.0-HBase-0.98)ClassNotFoundException

    我正在尝试通过 Spark 连接到 Phoenix 并且在通过 JDBC 驱动程序打开连接时不断收到以下异常 为简洁起见 下面是完整的堆栈跟踪 Caused by java lang ClassNotFoundException org a
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • Liferay ClassNotFoundException:DLFileEntryImpl

    在我的 6 1 0 Portal 实例上 带有使用 ServiceBuilder 和 DL Api 的 6 1 0 SDK Portlet 这一行 DynamicQuery query DynamicQueryFactoryUtil for
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • 如何为俚语和表情符号构建正则表达式 (regex)

    我需要构建一个正则表达式来匹配俚语 即 lol lmao imo 等 和表情符号 即 P 等 我按照以下示例进行操作http www coderanch com t 497238 java java Regular Expression D
  • Java按日期升序对列表对象进行排序[重复]

    这个问题在这里已经有答案了 我想按一个参数对对象列表进行排序 其日期格式为 YYYY MM DD HH mm 按升序排列 我找不到正确的解决方案 在 python 中使用 lambda 很容易对其进行排序 但在 Java 中我遇到了问题 f
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview

随机推荐

  • API 接口防刷(接口请求次数限制)

    目录 一 问题 1 解决 2 原理 二 实现 1 导入坐标 2 自定义注解 3 Redis 缓存工具类 4 自定义拦截器 5 WebConfig 配置类 6 异常处理器 1 异常标记码 1 通用对象返回类 7 Redis序列化配置 8 测试
  • 【Flink】yarn集群模式

    预备知识 Linux export 命令的生命周期 断开会话后 export 的环境变量不生效 支持会话级别的新增 删除和修改环境变量 用作之后的程序使用 仅仅用作此次会话期间 基于 YARN 模式部署 Flink 服务 3 1 基于 YA
  • 【SPI协议】

    一 SPI介绍 SPI是 全双工 通信 具有单独的发送和接收线 可以同时进行发送和接收 从机不主动发起访问 总是被动执行操作 SPI包含4根逻辑线 MISO 主机输入 从机输出 MOSI 主机输出 从机输入 SCLK 串行时钟信号 此信号由
  • 论文阅读:AAAI2022 Evaluating Explainable AI on a Multi-Modal Medical Imaging Task: Can Existing Algor...

    任务 explainable AI XAI 可解释性探索 主要提出两个指标 可以代替医生对事后可解释性算法进行评估 目的 多模态医学影像中存在的clinically important but technically ignored the
  • ModuleNotFoundError: No module named ‘xxx‘问题

    更换国内安装源和设置超时时间可以解决 pip install xxx default timeout 100 i https pypi tuna tsinghua edu cn simple 即可 安装源参考 超时时间参考
  • 【004】一天一道C/C++编程题

    第四题 请编写一个函数void fun char tt int pp 统计在tt字符串中 a 到 z 26个字母各自出现的次数 并依次放在pp所指数组中 例如 当输入字符串abcdefgabcdeabc后 程序的输出结果应该是 3 3 3
  • 面试题(2)

    1 J2EE是什么 2 介绍JAVA中的Collection FrameWork 包括如何写自己的数据结构 如COLLECTION中遗留类 HASHTABLE VECTOR 和现有类的区别 同步 3 Java中异常处理机制 事件机制 4 E
  • 实验7-3-8 统计字符出现次数(20 分)

    实验7 3 8 统计字符出现次数 20 分 本题要求编写程序 统计并输出某给定字符在给定字符串中出现的次数 输入格式 输入第一行给出一个以回车结束的字符串 少于80个字符 第二行输入一个字符 输出格式 在一行中输出给定字符在给定字符串中出现
  • 三位水仙花数的两种做法

    编写程序计算如下数列的值 1 2 3 4 966 其中 所有数字为整数 从1开始递增 奇数为正 偶数为负 s 0 for i in range 967
  • mybatis plus 写sql语句

    一 api public Map
  • app常见专项测试点

    常见的apk专项测试 主要有几类 主要指项目中经常用到的 1 稳定性 2 安全性 3 兼容性 4 版本升级 5 流量测试 6 实际测试总结 对整个项目团队是如何进行测试以及测试的内容 一 稳定性测试 稳定性测试是指对应用进行长时间的操作 检
  • jq+ajax提交合并表单,JQuery通过Ajax提交表单并返回结果

    如下 1 非Ajax 对应后台 2 JQuery之Ajax 在介绍使用JQuery提交表单前 我们需要首先引用jquery form js 它来自于http www malsup com jquery form 至此 我们需要引用的JS文件
  • Nice! I just got a Minecraft gift code for FREE! :D https://freeminecraftgiftcode.net

    Nice I just got a Minecraft gift code for FREE D https freeminecraftgiftcode net Nice I just got a Minecraft gift code f
  • Nodejs学习笔记 - 版本号

    npm outdated 查看过期了的包 也不能说过期 反正版本号不是最新的 就那么个意思 QWQ npm update 更新那个包 语言组织能力有点差 理解就行了 QWQ 进入正题了哇 版本号 eg 13 1 4 上边的版本号共分为3块
  • wind10 idea中 go 开发环境搭建

    下载安装包 国内的 不用翻墙 https studygolang com 官网 需翻墙 https golang org 这里使用的的是第一种https studygolang com 下载后解压到本地 目录结构 配置环境变量 path中配
  • while语句中的break和continue

    1 break介绍 include
  • 怎么彻底删除电脑上的软件_彻底删除流氓软件的两个工具!

    流氓软件 弹出广告 我想 这些应该让很多同学都苦不苦不堪言 卸载不干净 无法卸载 卸载残留 这些顽固的软件就如同牛皮癣一样 一旦粘着就很难摆脱 本文就来推荐2款软件 这两款都是经过多年使用 对比保留下来的 从此就可以对流氓软件说再见了 前言
  • android studio构建的AAB是什么

    AAB 是 Android App Bundle 的缩写 是一种由 Google 推出的 Android 应用程序发布格式 AAB 格式的应用程序包含了应用程序的所有代码和资源 但是与传统的 APK 包不同 AAB 包含了多个分割的模块 每
  • JAVA、MySql实现登录注册(网页)

    初学JAVA EE 老师留下一小作业 用JAVA实现与服务器端交互 实现登录和注册功能 初学一种专业课很多老师都会留下一种让学生实现登录和注册的作业 下面是记录的实现步骤 1 首先是账号密码输入框和按钮 登录
  • Sa-Token的Token有效期和临时有效期的区别

    各位不要再卷了 周六我在家打着游戏 群消息就一直叮叮叮 进去看了看 周六还加班干活 哎真卷 ps 在卷就没了 吐槽一下 进入正题 就周六群友提问做一下总结 群友问题 为什么 不能续期 先说一下这位群友的测试方法 token有效期 10秒 在