From d83640ab5ecd476a31286a1483c69abb7f67df51 Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Wed, 7 Jun 2023 13:14:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20active-timeout=20=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/dev33/satoken/stp/StpLogic.java | 75 +++++++++---------- .../cn/dev33/satoken/util/SaValue2Box.java | 2 +- .../src/main/resources/application.yml | 2 +- 3 files changed, 38 insertions(+), 41 deletions(-) diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java index a06861f9..49f0b677 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java @@ -614,7 +614,9 @@ public class StpLogic { session.removeTokenSign(tokenValue); // 2.3、清除这个 token 的最后活跃时间记录 - clearLastActive(tokenValue); + if(isOpenCheckActiveTimeout()) { + clearLastActive(tokenValue); + } // 2.4、清除 token -> id 的映射关系 deleteTokenToIdMapping(tokenValue); @@ -662,7 +664,9 @@ public class StpLogic { session.removeTokenSign(tokenValue); // 3.3、清除这个 token 的最后活跃时间记录 - clearLastActive(tokenValue); + if(isOpenCheckActiveTimeout()) { + clearLastActive(tokenValue); + } // 3.4、清除 token -> id 的映射关系 deleteTokenToIdMapping(tokenValue); @@ -685,7 +689,9 @@ public class StpLogic { */ public void logoutByTokenValue(String tokenValue) { // 1、清除这个 token 的最后活跃时间记录 - clearLastActive(tokenValue); + if(isOpenCheckActiveTimeout()) { + clearLastActive(tokenValue); + } // 2、清除这个 token 的 Token-Session 对象 deleteTokenSession(tokenValue); @@ -744,7 +750,9 @@ public class StpLogic { session.removeTokenSign(tokenValue); // 2.3、清除这个 token 的最后活跃时间记录 - clearLastActive(tokenValue); + if(isOpenCheckActiveTimeout()) { + clearLastActive(tokenValue); + } // 2.4、将此 token 标记为:已被踢下线 updateTokenToIdMapping(tokenValue, NotLoginException.KICK_OUT); @@ -769,7 +777,9 @@ public class StpLogic { */ public void kickoutByTokenValue(String tokenValue) { // 1、清除这个 token 的最后活跃时间记录 - clearLastActive(tokenValue); + if(isOpenCheckActiveTimeout()) { + clearLastActive(tokenValue); + } // 2、此处不需要清除它的 Token-Session 对象 // deleteTokenSession(tokenValue); @@ -816,7 +826,9 @@ public class StpLogic { session.removeTokenSign(tokenValue); // 2.3、清除这个 token 的最后活跃时间记录 - clearLastActive(tokenValue); + if(isOpenCheckActiveTimeout()) { + clearLastActive(tokenValue); + } // 2.4、将此 token 标记为:已被顶下线 updateTokenToIdMapping(tokenValue, NotLoginException.BE_REPLACED); @@ -894,16 +906,17 @@ public class StpLogic { throw NotLoginException.newInstance(loginType, KICK_OUT, KICK_OUT_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11015); } - // 7、检查此 token 的最后活跃时间是否已经超过了 active-timeout 的限制, - // 如果是则代表其已被冻结,需要抛出:token 已过期 - checkActiveTimeout(tokenValue); + // 7、检查此 token 的最后活跃时间是否已经超过了 active-timeout 的限制,如果是则代表其已被冻结,需要抛出:token 已被冻结 + if(isOpenCheckActiveTimeout()) { + checkActiveTimeout(tokenValue); - // ------ 至此,loginId 已经是一个合法的值,代表当前会话是一个正常的登录状态了 + // ------ 至此,loginId 已经是一个合法的值,代表当前会话是一个正常的登录状态了 - // 8、如果配置了自动续签功能, 则: 更新这个 token 的最后活跃时间 (注意此处的续签是在续 active-timeout,而非 timeout) - if(isOpenCheckActiveTimeout() && getConfig().getAutoRenew()) { - updateLastActiveToNow(tokenValue); - } + // 8、如果配置了自动续签功能, 则: 更新这个 token 的最后活跃时间 (注意此处的续签是在续 active-timeout,而非 timeout) + if(getConfig().getAutoRenew()) { + updateLastActiveToNow(tokenValue); + } + } // 9、返回 loginId return loginId; @@ -1345,7 +1358,7 @@ public class StpLogic { } // activeTimeout 变量无需赋值默认值,因为当缓存中没有这个值时,会自动使用全局配置的值 - // 将[ 最后活跃时间 ] 标记为当前时间戳 + // 将此 token 的 [ 最后活跃时间 ] 标记为当前时间戳 String key = splicingKeyLastActiveTime(tokenValue); String value = String.valueOf(System.currentTimeMillis()); if(config.getDynamicActiveTimeout() && activeTimeout != null) { @@ -1360,13 +1373,6 @@ public class StpLogic { * @param tokenValue 指定token */ public void updateLastActiveToNow(String tokenValue) { - // 如果提供的 token 无效,或者配置没有打开 token 活跃度校验, 则立即返回,无需操作 - if(SaFoxUtil.isEmpty(tokenValue) || ! isOpenCheckActiveTimeout() ) { - return; - } - - - // 将这个 token 的 [ 最后活跃时间 ] 更新为当前时间戳 String key = splicingKeyLastActiveTime(tokenValue); String value = new SaValue2Box(System.currentTimeMillis(), getTokenUseActiveTimeout(tokenValue)).toString(); getSaTokenDao().update(key, value); @@ -1389,15 +1395,7 @@ public class StpLogic { * @param tokenValue 指定 token */ protected void clearLastActive(String tokenValue) { - - // 如果提供的 token 无效,或者配置没有打开 token 活跃度校验, 则立即返回,无需操作 - if(SaFoxUtil.isEmpty(tokenValue) || ! isOpenCheckActiveTimeout() ) { - return; - } - - // 删除 [ 最后活跃时间 ] - String key = splicingKeyLastActiveTime(tokenValue); - getSaTokenDao().delete(key); + getSaTokenDao().delete(splicingKeyLastActiveTime(tokenValue)); } /** @@ -1407,13 +1405,7 @@ public class StpLogic { */ public void checkActiveTimeout(String tokenValue) { - // 如果提供的 token 无效,或者配置没有打开 token 活跃度校验, 则立即返回,无需操作 - if(SaFoxUtil.isEmpty(tokenValue) || ! isOpenCheckActiveTimeout() ) { - return; - } - - // 下面开始校验这个 token 是否已被冻结 - // storage.get(key, () -> {}) 可以避免一次请求多次校验,造成不必要的性能消耗 + // storage.get(key, () -> {}) 可以避免一次请求多次校验,造成不必要的性能消耗 SaStorage storage = SaHolder.getStorage(); storage.get(SaTokenConsts.TOKEN_ACTIVE_TIMEOUT_CHECKED_KEY, () -> { @@ -1449,11 +1441,16 @@ public class StpLogic { * @return / */ public Long getTokenUseActiveTimeout(String tokenValue) { + // 在未启用动态 activeTimeout 功能时,直接返回 null + if( ! getConfig().getDynamicActiveTimeout()) { + return null; + } + // 先取出这个 token 的最后活跃时间值 String key = splicingKeyLastActiveTime(tokenValue); String value = getSaTokenDao().get(key); - // 先获取缓存库里的值,获取不到则使用全局配置 + // 解析,无值的情况下返回 null SaValue2Box box = new SaValue2Box(value); return box.getValue2AsLong(null); } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaValue2Box.java b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaValue2Box.java index 6a9dcdbd..db627b64 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaValue2Box.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaValue2Box.java @@ -201,7 +201,7 @@ public class SaValue2Box { * System.out.println(new SaValue2Box(1, 2)); // 1,2 * System.out.println(new SaValue2Box(null, null)); // null * System.out.println(new SaValue2Box(1, null)); // 1 - * System.out.println(new SaValue2Box(null, 2)); // 2 + * System.out.println(new SaValue2Box(null, 2)); // ,2 * * @return / */ diff --git a/sa-token-demo/sa-token-demo-test/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-test/src/main/resources/application.yml index 33c83e8a..cce187f4 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-test/src/main/resources/application.yml @@ -9,7 +9,7 @@ sa-token: # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 - active-timeout: 100000 + active-timeout: -1 # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)