From 814a64907ad4901b8de75d882f2866f68af2d6cc Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Tue, 6 Jun 2023 06:18:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=99=BB=E5=BD=95=E6=97=B6?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=8C=87=E5=AE=9A=20active-timeout=20?= =?UTF-8?q?=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../satoken/annotation/SaCheckLogin.java | 2 +- .../dev33/satoken/annotation/SaCheckOr.java | 2 +- .../dev33/satoken/config/SaTokenConfig.java | 74 ++++- .../satoken/listener/SaTokenListener.java | 2 +- .../cn/dev33/satoken/stp/SaLoginConfig.java | 8 + .../cn/dev33/satoken/stp/SaLoginModel.java | 92 ++++--- .../cn/dev33/satoken/stp/SaTokenInfo.java | 20 +- .../java/cn/dev33/satoken/stp/StpLogic.java | 255 +++++++++++------- .../java/cn/dev33/satoken/stp/StpUtil.java | 30 +-- .../cn/dev33/satoken/util/SaTokenConsts.java | 15 +- .../cn/dev33/satoken/util/SaValue2Box.java | 219 +++++++++++++++ .../com/pj/cases/use/LoginAuthController.java | 2 +- .../main/java/com/pj/satoken/StpUserUtil.java | 34 ++- .../src/main/resources/application.yml | 18 +- .../src/main/resources/application.yml | 18 +- .../src/main/resources/application.yml | 22 +- .../main/java/com/pj/test/TestController.java | 8 +- .../src/main/resources/app.yml | 18 +- .../src/main/resources/application.yml | 18 +- .../src/main/resources/application.yml | 20 +- .../main/java/com/pj/test/TestController.java | 8 +- .../src/main/resources/application.yml | 20 +- .../src/main/resources/application.yml | 18 +- .../main/java/com/pj/satoken/StpUserUtil.java | 34 ++- .../main/java/com/pj/test/TestController.java | 11 +- .../src/main/resources/application.yml | 14 +- .../src/main/resources/application.yml | 18 +- .../src/main/resources/application.yml | 18 +- .../src/main/resources/application.yml | 20 +- .../src/main/resources/application.yml | 20 +- sa-token-doc/api/stp-util.md | 10 +- sa-token-doc/fun/exception-code.md | 2 +- sa-token-doc/fun/token-info.md | 2 +- sa-token-doc/fun/token-timeout.md | 36 +-- sa-token-doc/more/common-action.md | 18 +- sa-token-doc/more/common-questions.md | 2 +- sa-token-doc/more/noun-intro.md | 2 +- sa-token-doc/plugin/jwt-extend.md | 2 +- sa-token-doc/start/example.md | 30 +-- sa-token-doc/start/solon-example.md | 26 +- sa-token-doc/use/config.md | 36 +-- .../satoken/jwt/StpLogicJwtForMixin.java | 2 +- .../satoken/jwt/StpLogicJwtForStateless.java | 2 +- .../satoken/jboot/test/AtteStartListener.java | 2 +- .../cn/dev33/satoken/jfinal/test/Config.java | 2 +- .../src/test/resources/app.yml | 22 +- .../src/test/resources/application.yml | 16 +- .../core/config/SaTokenConfigTest.java | 6 +- .../dev33/satoken/core/stp/TokenInfoTest.java | 4 +- .../dev33/satoken/springboot/BasicsTest.java | 14 +- .../src/test/resources/sa-token2.properties | 16 +- 51 files changed, 835 insertions(+), 475 deletions(-) create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/util/SaValue2Box.java diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java index a9b6d715..f7af52a7 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckLogin.java @@ -25,7 +25,7 @@ import java.lang.annotation.Target; * *

可标注在方法、类上(效果等同于标注在此类的所有方法上) * - * @author kong + * @author click33 * @since 1.10.0 */ @Retention(RetentionPolicy.RUNTIME) diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckOr.java b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckOr.java index e9cef129..b008f083 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckOr.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/annotation/SaCheckOr.java @@ -25,7 +25,7 @@ import java.lang.annotation.Target; * *

可标注在方法、类上(效果等同于标注在此类的所有方法上) * - * @author kong + * @author click33 * @since 1.35.0 */ @Retention(RetentionPolicy.RUNTIME) diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java index 4cff2cb2..fa0d7379 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java @@ -15,6 +15,7 @@ */ package cn.dev33.satoken.config; +import cn.dev33.satoken.SaManager; import cn.dev33.satoken.util.SaFoxUtil; import java.io.Serializable; @@ -37,14 +38,19 @@ public class SaTokenConfig implements Serializable { /** token 名称 (同时也是: cookie 名称、提交 token 时参数的名称、存储 token 时的 key 前缀) */ private String tokenName = "satoken"; - /** token 有效期(单位:秒) 默认30天,-1 代表永久 */ + /** token 有效期(单位:秒) 默认30天,-1 代表永久有效 */ private long timeout = 60 * 60 * 24 * 30; /** * token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 * (例如可以设置为 1800 代表 30 分钟内无操作就冻结) */ - private long activityTimeout = -1; + private long activeTimeout = -1; + + /** + * 是否启用动态 activeTimeout 功能,如不需要请设置为 false,节省缓存请求次数 + */ + private Boolean dynamicActiveTimeout = false; /** * 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) @@ -102,7 +108,7 @@ public class SaTokenConfig implements Serializable { private Boolean tokenSessionCheckLogin = true; /** - * 是否打开自动续签 activityTimeout (如果此值为 true, 框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) + * 是否打开自动续签 activeTimeout (如果此值为 true, 框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) */ private Boolean autoRenew = true; @@ -189,14 +195,14 @@ public class SaTokenConfig implements Serializable { } /** - * @return token 有效期(单位:秒) 默认30天,-1 代表永久 + * @return token 有效期(单位:秒) 默认30天,-1 代表永久有效 */ public long getTimeout() { return timeout; } /** - * @param timeout token 有效期(单位:秒) 默认30天,-1 代表永久 + * @param timeout token 有效期(单位:秒) 默认30天,-1 代表永久有效 * @return 对象自身 */ public SaTokenConfig setTimeout(long timeout) { @@ -208,17 +214,33 @@ public class SaTokenConfig implements Serializable { * @return token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 * (例如可以设置为 1800 代表 30 分钟内无操作就冻结) */ - public long getActivityTimeout() { - return activityTimeout; + public long getActiveTimeout() { + return activeTimeout; } /** - * @param activityTimeout token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + * @param activeTimeout token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 * (例如可以设置为 1800 代表 30 分钟内无操作就冻结) * @return 对象自身 */ - public SaTokenConfig setActivityTimeout(long activityTimeout) { - this.activityTimeout = activityTimeout; + public SaTokenConfig setActiveTimeout(long activeTimeout) { + this.activeTimeout = activeTimeout; + return this; + } + + /** + * @return 是否启用动态 activeTimeout 功能,如不需要请设置为 false,节省缓存请求次数 + */ + public Boolean getDynamicActiveTimeout() { + return dynamicActiveTimeout; + } + + /** + * @param dynamicActiveTimeout 是否启用动态 activeTimeout 功能,如不需要请设置为 false,节省缓存请求次数 + * @return 对象自身 + */ + public SaTokenConfig setDynamicActiveTimeout(Boolean dynamicActiveTimeout) { + this.dynamicActiveTimeout = dynamicActiveTimeout; return this; } @@ -399,14 +421,14 @@ public class SaTokenConfig implements Serializable { } /** - * @return 是否打开自动续签 activityTimeout (如果此值为 true, 框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) + * @return 是否打开自动续签 activeTimeout (如果此值为 true, 框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) */ public Boolean getAutoRenew() { return autoRenew; } /** - * @param autoRenew 是否打开自动续签 activityTimeout (如果此值为 true, 框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) + * @param autoRenew 是否打开自动续签 activeTimeout (如果此值为 true, 框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作) * @return 对象自身 */ public SaTokenConfig setAutoRenew(Boolean autoRenew) { @@ -633,7 +655,8 @@ public class SaTokenConfig implements Serializable { return "SaTokenConfig [" + "tokenName=" + tokenName + ", timeout=" + timeout - + ", activityTimeout=" + activityTimeout + + ", activeTimeout=" + activeTimeout + + ", dynamicActiveTimeout=" + dynamicActiveTimeout + ", isConcurrent=" + isConcurrent + ", isShare=" + isShare + ", maxLoginCount=" + maxLoginCount @@ -662,4 +685,29 @@ public class SaTokenConfig implements Serializable { + "]"; } + /** + * 请更改为 getActiveTimeout() + * @return token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + * (例如可以设置为 1800 代表 30 分钟内无操作就冻结) + */ + @Deprecated + public long getActivityTimeout() { + System.err.println("配置项已过期,请更换:sa-token.activity-timeout -> sa-token.active-timeout"); + return activeTimeout; + } + + /** + * 请更改为 setActiveTimeout() + * @param activityTimeout token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + * (例如可以设置为 1800 代表 30 分钟内无操作就冻结) + * @return 对象自身 + */ + @Deprecated + public SaTokenConfig setActivityTimeout(long activityTimeout) { + System.err.println("配置项已过期,请更换:sa-token.activity-timeout -> sa-token.active-timeout"); + this.activeTimeout = activityTimeout; + return this; + } + + } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListener.java b/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListener.java index 09dc9739..4de64e2e 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListener.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListener.java @@ -110,7 +110,7 @@ public interface SaTokenListener { void doLogoutSession(String id); /** - * 每次 Token 续期时触发(注意:是 timeout 续期,而不是 activity-timeout 续期) + * 每次 Token 续期时触发(注意:是 timeout 续期,而不是 active-timeout 续期) * * @param tokenValue token 值 * @param loginId 账号id diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginConfig.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginConfig.java index 8f433afd..26353970 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginConfig.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginConfig.java @@ -60,6 +60,14 @@ public class SaLoginConfig { return create().setTimeout(timeout); } + /** + * @param activeTimeout 指定此次登录 token 最低活跃频率,单位:秒(如未指定,自动取全局配置的 activeTimeout 值) + * @return 对象自身 + */ + public static SaLoginModel setActiveTimeout(long activeTimeout) { + return create().setActiveTimeout(activeTimeout); + } + /** * @param extraData 扩展信息(只在jwt模式下生效) * @return 登录参数 Model diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java index 37d65f5e..b724837a 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java @@ -47,10 +47,15 @@ public class SaLoginModel { public Boolean isLastingCookie = true; /** - * 指定此次登录token的有效期, 单位:秒 (如未指定,自动取全局配置的timeout值) + * 指定此次登录 token 有效期,单位:秒 (如未指定,自动取全局配置的 timeout 值) */ public Long timeout; + /** + * 指定此次登录 token 最低活跃频率,单位:秒(如未指定,则使用全局配置的 activeTimeout 值) + */ + private Long activeTimeout; + /** * 扩展信息(只在jwt模式下生效) */ @@ -91,16 +96,6 @@ public class SaLoginModel { return isLastingCookie; } - /** - * @return 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在) - */ - public Boolean getIsLastingCookieOrFalse() { - if(isLastingCookie == null) { - return false; - } - return isLastingCookie; - } - /** * @param isLastingCookie 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在) * @return 对象自身 @@ -111,24 +106,14 @@ public class SaLoginModel { } /** - * @return 指定此次登录token的有效期, 单位:秒 (如未指定,自动取全局配置的timeout值) + * @return 指定此次登录 token 有效期,单位:秒 */ public Long getTimeout() { return timeout; } /** - * @return timeout 值 (如果此配置项尚未配置,则取全局配置的值) - */ - public Long getTimeoutOrGlobalConfig() { - if(timeout == null) { - timeout = SaManager.getConfig().getTimeout(); - } - return timeout; - } - - /** - * @param timeout 指定此次登录token的有效期, 单位:秒 (如未指定,自动取全局配置的timeout值) + * @param timeout 指定此次登录 token 有效期,单位:秒 (如未指定,自动取全局配置的 timeout 值) * @return 对象自身 */ public SaLoginModel setTimeout(long timeout) { @@ -136,6 +121,23 @@ public class SaLoginModel { return this; } + /** + * @return 此次登录 token 最低活跃频率,单位:秒(如未指定,则使用全局配置的 activeTimeout 值) + */ + public Long getActiveTimeout() { + return activeTimeout; + } + + + /** + * @param activeTimeout 指定此次登录 token 最低活跃频率,单位:秒(如未指定,则使用全局配置的 activeTimeout 值) + * @return 对象自身 + */ + public SaLoginModel setActiveTimeout(long activeTimeout) { + this.activeTimeout = activeTimeout; + return this; + } + /** * @return 扩展信息(只在jwt模式下生效) */ @@ -175,16 +177,6 @@ public class SaLoginModel { return isWriteHeader; } - /** - * @return 是否在登录后将 Token 写入到响应头 (如果此配置项尚未配置,则取全局配置的值) - */ - public Boolean getIsWriteHeaderOrGlobalConfig() { - if(isWriteHeader == null) { - isWriteHeader = SaManager.getConfig().getIsWriteHeader(); - } - return isWriteHeader; - } - /** * @param isWriteHeader 是否在登录后将 Token 写入到响应头 * @return 对象自身 @@ -213,6 +205,7 @@ public class SaLoginModel { this.tokenSignTag = tokenSignTag; return this; } + /* * toString */ @@ -222,6 +215,7 @@ public class SaLoginModel { + "device=" + device + ", isLastingCookie=" + isLastingCookie + ", timeout=" + timeout + + ", activeTimeout=" + activeTimeout + ", extraData=" + extraData + ", token=" + token + ", isWriteHeader=" + isWriteHeader @@ -232,6 +226,36 @@ public class SaLoginModel { // ------ 附加方法 + /** + * @return 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在) + */ + public Boolean getIsLastingCookieOrFalse() { + if(isLastingCookie == null) { + return false; + } + return isLastingCookie; + } + + /** + * @return timeout 值 (如果此配置项尚未配置,则取全局配置的值) + */ + public Long getTimeoutOrGlobalConfig() { + if(timeout == null) { + timeout = SaManager.getConfig().getTimeout(); + } + return timeout; + } + + /** + * @return 是否在登录后将 Token 写入到响应头 (如果此配置项尚未配置,则取全局配置的值) + */ + public Boolean getIsWriteHeaderOrGlobalConfig() { + if(isWriteHeader == null) { + isWriteHeader = SaManager.getConfig().getIsWriteHeader(); + } + return isWriteHeader; + } + /** * 写入扩展数据(只在jwt模式下生效) * @param key 键 @@ -288,7 +312,7 @@ public class SaLoginModel { } return device; } - + /** * 构建对象,初始化默认值 * @return 对象自身 diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaTokenInfo.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaTokenInfo.java index a86a1728..86c5aeae 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaTokenInfo.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaTokenInfo.java @@ -30,7 +30,7 @@ package cn.dev33.satoken.stp; * "tokenTimeout": 2591977, // token剩余有效期 (单位: 秒) * "sessionTimeout": 2591977, // Account-Session剩余有效时间 (单位: 秒) * "tokenSessionTimeout": -2, // Token-Session剩余有效时间 (单位: 秒) (-2表示系统中不存在这个缓存) - * "tokenActivityTimeout": -1, // token剩余无操作有效时间 (单位: 秒) + * "tokenActiveTimeout": -1, // Token 距离被冻结还剩多少时间 (单位: 秒) * "loginDevice": "default-device" // 登录设备类型 * } * @@ -65,8 +65,8 @@ public class SaTokenInfo { /** Token-Session 剩余有效时间(单位: 秒) */ public long tokenSessionTimeout; - /** token 剩余无操作有效时间(单位: 秒) */ - public long tokenActivityTimeout; + /** token 距离被冻结还剩多少时间(单位: 秒) */ + public long tokenActiveTimeout; /** 登录设备类型 */ public String loginDevice; @@ -189,17 +189,17 @@ public class SaTokenInfo { } /** - * @return token 剩余无操作有效时间(单位: 秒) + * @return token 距离被冻结还剩多少时间(单位: 秒) */ - public long getTokenActivityTimeout() { - return tokenActivityTimeout; + public long getTokenActiveTimeout() { + return tokenActiveTimeout; } /** - * @param tokenActivityTimeout token 剩余无操作有效时间(单位: 秒) + * @param tokenActiveTimeout token 距离被冻结还剩多少时间(单位: 秒) */ - public void setTokenActivityTimeout(long tokenActivityTimeout) { - this.tokenActivityTimeout = tokenActivityTimeout; + public void setTokenActiveTimeout(long tokenActiveTimeout) { + this.tokenActiveTimeout = tokenActiveTimeout; } /** @@ -238,7 +238,7 @@ public class SaTokenInfo { return "SaTokenInfo [tokenName=" + tokenName + ", tokenValue=" + tokenValue + ", isLogin=" + isLogin + ", loginId=" + loginId + ", loginType=" + loginType + ", tokenTimeout=" + tokenTimeout + ", sessionTimeout=" + sessionTimeout + ", tokenSessionTimeout=" + tokenSessionTimeout - + ", tokenActivityTimeout=" + tokenActivityTimeout + ", loginDevice=" + loginDevice + ", tag=" + tag + + ", tokenActiveTimeout=" + tokenActiveTimeout + ", loginDevice=" + loginDevice + ", tag=" + tag + "]"; } 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 850804db..a06861f9 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 @@ -34,6 +34,7 @@ import cn.dev33.satoken.session.TokenSign; import cn.dev33.satoken.strategy.SaStrategy; import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaTokenConsts; +import cn.dev33.satoken.util.SaValue2Box; import java.util.ArrayList; import java.util.Collections; @@ -342,7 +343,7 @@ public class StpLogic { info.tokenTimeout = getTokenTimeout(); info.sessionTimeout = getSessionTimeout(); info.tokenSessionTimeout = getTokenSessionTimeout(); - info.tokenActivityTimeout = getTokenActivityTimeout(); + info.tokenActiveTimeout = getTokenActiveTimeout(); info.loginDevice = getLoginDevice(); return info; } @@ -401,7 +402,7 @@ public class StpLogic { // 1、创建会话 String token = createLoginSession(id, loginModel); - // 2、在当前客户端注入Token + // 2、在当前客户端注入 token setTokenValue(token, loginModel); } @@ -445,8 +446,10 @@ public class StpLogic { // 6、保存 token -> id 的映射关系,方便日后根据 token 找账号 id saveTokenToIdMapping(tokenValue, id, loginModel.getTimeout()); - // 7、写入这个 token 的最后活跃时间 token-last-activity - setLastActivityToNow(tokenValue); + // 7、写入这个 token 的最后活跃时间 token-last-active + if(isOpenCheckActiveTimeout()) { + setLastActiveToNow(tokenValue, loginModel.getActiveTimeout(), loginModel.getTimeoutOrGlobalConfig()); + } // 8、$$ 发布全局事件:账号 xxx 登录成功 SaTokenEventCenter.doLogin(loginType, id, tokenValue, loginModel); @@ -541,10 +544,15 @@ public class StpLogic { // 如果不支持,开发者却传入了 extra 扩展参数,那么就打印警告信息 Map extraData = loginModel.getExtraData(); if(extraData != null && extraData.size() > 0) { - SaManager.log.warn("当前 StpLogic 不支持 extra 扩展参数模式,传入的 extra 数据将被忽略"); + SaManager.log.warn("当前 StpLogic 不支持 extra 扩展参数模式,传入的 extra 参数将被忽略"); } } + // 5、如果全局配置未启动动态 activeTimeout 功能,但是此次登录却传入了 activeTimeout 参数,那么就打印警告信息 + if( ! getConfig().getDynamicActiveTimeout() && loginModel.getActiveTimeout() != null) { + SaManager.log.warn("当前全局配置未开启动态 activeTimeout 功能,传入的 activeTimeout 参数将被忽略"); + } + } // --- 注销 @@ -570,7 +578,7 @@ public class StpLogic { storage.delete(splicingKeyJustCreatedSave()); // 4、清除当前上下文的 [ 活跃度校验 check 标记 ] - storage.delete(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY); + storage.delete(SaTokenConsts.TOKEN_ACTIVE_TIMEOUT_CHECKED_KEY); // 5、清除这个 token 的其它相关信息 logoutByTokenValue(tokenValue); @@ -606,7 +614,7 @@ public class StpLogic { session.removeTokenSign(tokenValue); // 2.3、清除这个 token 的最后活跃时间记录 - clearLastActivity(tokenValue); + clearLastActive(tokenValue); // 2.4、清除 token -> id 的映射关系 deleteTokenToIdMapping(tokenValue); @@ -654,7 +662,7 @@ public class StpLogic { session.removeTokenSign(tokenValue); // 3.3、清除这个 token 的最后活跃时间记录 - clearLastActivity(tokenValue); + clearLastActive(tokenValue); // 3.4、清除 token -> id 的映射关系 deleteTokenToIdMapping(tokenValue); @@ -677,7 +685,7 @@ public class StpLogic { */ public void logoutByTokenValue(String tokenValue) { // 1、清除这个 token 的最后活跃时间记录 - clearLastActivity(tokenValue); + clearLastActive(tokenValue); // 2、清除这个 token 的 Token-Session 对象 deleteTokenSession(tokenValue); @@ -736,7 +744,7 @@ public class StpLogic { session.removeTokenSign(tokenValue); // 2.3、清除这个 token 的最后活跃时间记录 - clearLastActivity(tokenValue); + clearLastActive(tokenValue); // 2.4、将此 token 标记为:已被踢下线 updateTokenToIdMapping(tokenValue, NotLoginException.KICK_OUT); @@ -761,7 +769,7 @@ public class StpLogic { */ public void kickoutByTokenValue(String tokenValue) { // 1、清除这个 token 的最后活跃时间记录 - clearLastActivity(tokenValue); + clearLastActive(tokenValue); // 2、此处不需要清除它的 Token-Session 对象 // deleteTokenSession(tokenValue); @@ -808,7 +816,7 @@ public class StpLogic { session.removeTokenSign(tokenValue); // 2.3、清除这个 token 的最后活跃时间记录 - clearLastActivity(tokenValue); + clearLastActive(tokenValue); // 2.4、将此 token 标记为:已被顶下线 updateTokenToIdMapping(tokenValue, NotLoginException.BE_REPLACED); @@ -886,15 +894,15 @@ public class StpLogic { throw NotLoginException.newInstance(loginType, KICK_OUT, KICK_OUT_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11015); } - // 7、检查此 token 的最后活跃时间是否已经超过了 activity-timeout 的限制, + // 7、检查此 token 的最后活跃时间是否已经超过了 active-timeout 的限制, // 如果是则代表其已被冻结,需要抛出:token 已过期 - checkActivityTimeout(tokenValue); + checkActiveTimeout(tokenValue); // ------ 至此,loginId 已经是一个合法的值,代表当前会话是一个正常的登录状态了 - // 8、如果配置了自动续签功能, 则: 更新这个 token 的最后活跃时间 (注意此处的续签是在续 activity-timeout,而非 timeout) - if(getConfig().getAutoRenew()) { - updateLastActivityToNow(tokenValue); + // 8、如果配置了自动续签功能, 则: 更新这个 token 的最后活跃时间 (注意此处的续签是在续 active-timeout,而非 timeout) + if(isOpenCheckActiveTimeout() && getConfig().getAutoRenew()) { + updateLastActiveToNow(tokenValue); } // 9、返回 loginId @@ -947,7 +955,7 @@ public class StpLogic { } // 4、如果 token 已被冻结,也返回 null - if(getTokenActivityTimeoutByToken(tokenValue) == SaTokenDao.NOT_VALUE_EXPIRE) { + if(getTokenActiveTimeoutByToken(tokenValue) == SaTokenDao.NOT_VALUE_EXPIRE) { return null; } @@ -1285,7 +1293,9 @@ public class StpLogic { ); // 写入此 token 的最后活跃时间 - setLastActivityToNow(tokenValue); + if(isOpenCheckActiveTimeout()) { + setLastActiveToNow(tokenValue, null, null); + } // 在当前上下文写入此 TokenValue setTokenValue(tokenValue); @@ -1317,38 +1327,77 @@ public class StpLogic { } - // ------------------- Activity-Timeout token 最低活跃度 验证相关 ------------------- + // ------------------- Active-Timeout token 最低活跃度 验证相关 ------------------- /** - * 写入指定 token 的 [ 最后活跃时间 ] 为当前时间戳 + * 写入指定 token 的 [ 最后活跃时间 ] 为当前时间戳 √√√ * - * @param tokenValue 指定token + * @param tokenValue 指定token + * @param activeTimeout 这个 token 的最低活跃频率,单位:秒,填 null 代表使用全局配置的 activeTimeout 值 + * @param timeout 保存数据时使用的 ttl 值,单位:秒,填 null 代表使用全局配置的 timeout 值 */ - protected void setLastActivityToNow(String tokenValue) { + protected void setLastActiveToNow(String tokenValue, Long activeTimeout, Long timeout) { - // 如果提供的 token 无效,或者配置没有打开 token 活跃度校验, 则立即返回,无需操作 - if(SaFoxUtil.isEmpty(tokenValue) || ! isOpenActivityCheck() ) { - return; - } + // 如果提供的 timeout 为null,则使用全局配置的 timeout 值 + SaTokenConfig config = getConfig(); + if(timeout == null) { + timeout = config.getTimeout(); + } + // activeTimeout 变量无需赋值默认值,因为当缓存中没有这个值时,会自动使用全局配置的值 // 将[ 最后活跃时间 ] 标记为当前时间戳 - getSaTokenDao().set(splicingKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()), getConfig().getTimeout()); + String key = splicingKeyLastActiveTime(tokenValue); + String value = String.valueOf(System.currentTimeMillis()); + if(config.getDynamicActiveTimeout() && activeTimeout != null) { + value += "," + activeTimeout; + } + getSaTokenDao().set(key, value, timeout); } - - /** + + /** + * 续签指定 token:将这个 token 的 [ 最后活跃时间 ] 更新为当前时间戳 + * + * @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); + } + + /** + * 续签当前 token:(将 [最后操作时间] 更新为当前时间戳) + *

+ * 请注意: 即使 token 已被冻结 也可续签成功, + * 如果此场景下需要提示续签失败,可在此之前调用 checkActiveTimeout() 强制检查是否冻结即可 + *

+ */ + public void updateLastActiveToNow() { + updateLastActiveToNow(getTokenValue()); + } + + /** * 清除指定 Token 的 [ 最后活跃时间记录 ] * * @param tokenValue 指定 token */ - protected void clearLastActivity(String tokenValue) { + protected void clearLastActive(String tokenValue) { // 如果提供的 token 无效,或者配置没有打开 token 活跃度校验, 则立即返回,无需操作 - if(SaFoxUtil.isEmpty(tokenValue) || ! isOpenActivityCheck() ) { + if(SaFoxUtil.isEmpty(tokenValue) || ! isOpenCheckActiveTimeout() ) { return; } // 删除 [ 最后活跃时间 ] - getSaTokenDao().delete(splicingKeyLastActivityTime(tokenValue)); + String key = splicingKeyLastActiveTime(tokenValue); + getSaTokenDao().delete(key); } /** @@ -1356,73 +1405,72 @@ public class StpLogic { * * @param tokenValue 指定 token */ - public void checkActivityTimeout(String tokenValue) { + public void checkActiveTimeout(String tokenValue) { // 如果提供的 token 无效,或者配置没有打开 token 活跃度校验, 则立即返回,无需操作 - if(SaFoxUtil.isEmpty(tokenValue) || ! isOpenActivityCheck() ) { + if(SaFoxUtil.isEmpty(tokenValue) || ! isOpenCheckActiveTimeout() ) { return; } - // 如果本次请求已经有了 [ 检查标记 ],说明已经校验过了,此时无需重复校验,立即返回 + // 下面开始校验这个 token 是否已被冻结 + // storage.get(key, () -> {}) 可以避免一次请求多次校验,造成不必要的性能消耗 SaStorage storage = SaHolder.getStorage(); - if(storage.get(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY) != null) { - return; - } + storage.get(SaTokenConsts.TOKEN_ACTIVE_TIMEOUT_CHECKED_KEY, () -> { - // ------------ 下面开始校验这个 token 是否已被冻结 + // 1、获取这个 token 的剩余活跃有效期 + long activeTimeout = getTokenActiveTimeoutByToken(tokenValue); - // 1、获取这个 token 的剩余活跃有效期 - long timeout = getTokenActivityTimeoutByToken(tokenValue); + // 2、值为 -1 代表此 token 已经被设置永不冻结,无须继续验证 + if(activeTimeout == SaTokenDao.NEVER_EXPIRE) { + return true; + } - // 2、值为 -1 代表此 token 已经被设置永不冻结,无须继续验证 - if(timeout == SaTokenDao.NEVER_EXPIRE) { - // 此句代码含义参考最下面 - storage.set(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY, true); - return; - } + // 3、值为 -2 代表已被冻结,此时需要抛出异常 + if(activeTimeout == SaTokenDao.NOT_VALUE_EXPIRE) { + throw NotLoginException.newInstance(loginType, TOKEN_FREEZE, TOKEN_FREEZE_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11016); + } - // 3、值为 -2 代表已被冻结,此时需要抛出异常 - if(timeout == SaTokenDao.NOT_VALUE_EXPIRE) { - throw NotLoginException.newInstance(loginType, TOKEN_FREEZE, TOKEN_FREEZE_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11016); - } - // --- 至此,验证已通过 - - // 4、打上 [ 检查标记 ],标记一下当前请求已经通过校验,避免一次请求多次校验,造成不必要的性能消耗 - storage.set(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY, true); + // --- 验证通过 + return true; + }); } /** * 检查当前 token 是否已被冻结,如果是则抛出异常 */ - public void checkActivityTimeout() { - checkActivityTimeout(getTokenValue()); + public void checkActiveTimeout() { + checkActiveTimeout(getTokenValue()); } - - /** - * 续签指定 token:将这个 token 的 [ 最后活跃时间 ] 更新为当前时间戳 + + /** + * 获取指定 token 在缓存中的 activeTimeout 值,如果不存在则返回 null * - * @param tokenValue 指定token - */ - public void updateLastActivityToNow(String tokenValue) { - // 如果提供的 token 无效,或者配置没有打开 token 活跃度校验, 则立即返回,无需操作 - if(SaFoxUtil.isEmpty(tokenValue) || ! isOpenActivityCheck() ) { - return; + * @param tokenValue 指定token + * @return / + */ + public Long getTokenUseActiveTimeout(String tokenValue) { + // 先取出这个 token 的最后活跃时间值 + String key = splicingKeyLastActiveTime(tokenValue); + String value = getSaTokenDao().get(key); + + // 先获取缓存库里的值,获取不到则使用全局配置 + SaValue2Box box = new SaValue2Box(value); + return box.getValue2AsLong(null); + } + + /** + * 获取指定 token 在缓存中的 activeTimeout 值,如果不存在则返回全局配置的 activeTimeout 值 + * + * @param tokenValue 指定token + * @return / + */ + public long getTokenUseActiveTimeoutOrGlobalConfig(String tokenValue) { + Long activeTimeout = getTokenUseActiveTimeout(tokenValue); + if(activeTimeout == null) { + return getConfig().getActiveTimeout(); } - - // 将这个 token 的 [ 最后活跃时间 ] 更新为当前时间戳 - getSaTokenDao().update(splicingKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis())); - } - - /** - * 续签当前 token:(将 [最后操作时间] 更新为当前时间戳) - *

- * 请注意: 即使 token 已被冻结 也可续签成功, - * 如果此场景下需要提示续签失败,可在此之前调用 checkActivityTimeout() 强制检查是否冻结即可 - *

- */ - public void updateLastActivityToNow() { - updateLastActivityToNow(getTokenValue()); - } + return activeTimeout; + } // ------------------- 过期时间相关 ------------------- @@ -1499,8 +1547,8 @@ public class StpLogic { * * @return / */ - public long getTokenActivityTimeout() { - return getTokenActivityTimeoutByToken(getTokenValue()); + public long getTokenActiveTimeout() { + return getTokenActiveTimeoutByToken(getTokenValue()); } /** @@ -1509,10 +1557,10 @@ public class StpLogic { * @param tokenValue 指定 token * @return / */ - public long getTokenActivityTimeoutByToken(String tokenValue) { + public long getTokenActiveTimeoutByToken(String tokenValue) { // 如果全局配置了永不冻结, 则返回 -1 - if( ! isOpenActivityCheck() ) { + if( ! isOpenCheckActiveTimeout() ) { return SaTokenDao.NEVER_EXPIRE; } @@ -1524,27 +1572,32 @@ public class StpLogic { // ------ 开始查询 // 1、先获取这个 token 的最后活跃时间,13位时间戳 - String keyLastActivityTime = splicingKeyLastActivityTime(tokenValue); - String lastActivityTimeString = getSaTokenDao().get(keyLastActivityTime); + String key = splicingKeyLastActiveTime(tokenValue); + String lastActiveTimeString = getSaTokenDao().get(key); + // 2、如果查不到,返回-2 - if(lastActivityTimeString == null) { + if(lastActiveTimeString == null) { return SaTokenDao.NOT_VALUE_EXPIRE; } - // 3、计算最后活跃时间 和 此时此刻 的时间差 + // 3、计算最后活跃时间 距离 此时此刻 的时间差 // 计算公式为: (当前时间 - 最后活跃时间) / 1000 - long lastActivityTime = Long.parseLong(lastActivityTimeString); - long apartSecond = (System.currentTimeMillis() - lastActivityTime) / 1000; + SaValue2Box box = new SaValue2Box(lastActiveTimeString); + long lastActiveTime = box.getValue1AsLong(); + // 实际时间差 + long timeDiff = (System.currentTimeMillis() - lastActiveTime) / 1000; + // 该 token 允许的时间差 + long allowTimeDiff = getTokenUseActiveTimeoutOrGlobalConfig(tokenValue); // 4、校验这个时间差是否超过了允许的值 // 计算公式为: 允许的最大时间差 - 实际时间差,判断是否 < 0, 如果是则代表已经被冻结 ,返回-2 - long timeout = getConfig().getActivityTimeout() - apartSecond; - if(timeout < 0) { + long activeTimeout = allowTimeDiff - timeDiff; + if(activeTimeout < 0) { return SaTokenDao.NOT_VALUE_EXPIRE; } else { // 否则代表没冻结,返回剩余有效时间 - return timeout; + return activeTimeout; } } @@ -1597,8 +1650,8 @@ public class StpLogic { getSessionByLoginId(loginId).updateMinTimeout(timeout); // 5、更新此 token 的最后活跃时间 - if(isOpenActivityCheck()) { - dao.updateTimeout(splicingKeyLastActivityTime(tokenValue), timeout); + if(isOpenCheckActiveTimeout()) { + dao.updateTimeout(splicingKeyLastActiveTime(tokenValue), timeout); } // 6、$$ 发布事件:某某 token 被续期了 @@ -2603,8 +2656,8 @@ public class StpLogic { * @param tokenValue token值 * @return key */ - public String splicingKeyLastActivityTime(String tokenValue) { - return getConfig().getTokenName() + ":" + loginType + ":last-activity:" + tokenValue; + public String splicingKeyLastActiveTime(String tokenValue) { + return getConfig().getTokenName() + ":" + loginType + ":last-active:" + tokenValue; } /** @@ -2677,8 +2730,8 @@ public class StpLogic { * * @return / */ - public boolean isOpenActivityCheck() { - return getConfig().getActivityTimeout() != SaTokenDao.NEVER_EXPIRE; + public boolean isOpenCheckActiveTimeout() { + return getConfig().getActiveTimeout() != SaTokenDao.NEVER_EXPIRE; } /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java index 0b478b3b..945c88d9 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java @@ -26,7 +26,7 @@ import java.util.List; * Sa-Token 权限认证工具类 * * @author click33 - * @since 1.10.0 + * @since 1.0.0 */ public class StpUtil { @@ -493,26 +493,26 @@ public class StpUtil { } - // ------------------- Activity-Timeout token 最低活跃度 验证相关 ------------------- - - /** - * 检查当前 token 是否已被冻结,如果是则抛出异常 - */ - public static void checkActivityTimeout() { - stpLogic.checkActivityTimeout(); - } + // ------------------- Active-Timeout token 最低活跃度 验证相关 ------------------- /** * 续签当前 token:(将 [最后操作时间] 更新为当前时间戳) *

* 请注意: 即使 token 已被冻结 也可续签成功, - * 如果此场景下需要提示续签失败,可在此之前调用 checkActivityTimeout() 强制检查是否冻结即可 + * 如果此场景下需要提示续签失败,可在此之前调用 checkActiveTimeout() 强制检查是否冻结即可 *

*/ - public static void updateLastActivityToNow() { - stpLogic.updateLastActivityToNow(); + public static void updateLastActiveToNow() { + stpLogic.updateLastActiveToNow(); + } + + /** + * 检查当前 token 是否已被冻结,如果是则抛出异常 + */ + public static void checkActiveTimeout() { + stpLogic.checkActiveTimeout(); } - + // ------------------- 过期时间相关 ------------------- @@ -558,8 +558,8 @@ public class StpUtil { * * @return / */ - public static long getTokenActivityTimeout() { - return stpLogic.getTokenActivityTimeout(); + public static long getTokenActiveTimeout() { + return stpLogic.getTokenActiveTimeout(); } /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java index 21eb2db7..2c2d94d8 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java @@ -67,9 +67,9 @@ public class SaTokenConsts { public static final String JUST_CREATED_NOT_PREFIX = "JUST_CREATED_NOT_PREFIX_"; /** - * 常量 key 标记: 如果本次请求已经验证过 [ 临时过期 ] , 则以此值存储在当前 request 中 + * 常量 key 标记: 如果本次请求已经验证过 activeTimeout, 则以此 key 在 storage 中做一个标记 */ - public static final String TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY = "TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY_"; + public static final String TOKEN_ACTIVE_TIMEOUT_CHECKED_KEY = "TOKEN_ACTIVE_TIMEOUT_CHECKED_KEY_"; /** * 常量 key 标记: 在登录时,默认使用的设备类型 @@ -193,6 +193,13 @@ public class SaTokenConsts { * 请更换为 JUST_CREATED */ @Deprecated - public static final String JUST_CREATED_SAVE_KEY = JUST_CREATED; - + public static final String JUST_CREATED_SAVE_KEY = JUST_CREATED; + + /** + * 请更换为 TOKEN_ACTIVE_TIMEOUT_CHECKED_KEY + */ + @Deprecated + public static final String TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY = TOKEN_ACTIVE_TIMEOUT_CHECKED_KEY; + + } 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 new file mode 100644 index 00000000..6a9dcdbd --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaValue2Box.java @@ -0,0 +1,219 @@ +/* + * Copyright 2020-2099 sa-token.cc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.dev33.satoken.util; + + +/** + * 封装两个值的容器,方便取值、写值等操作,value1 和 value2 用逗号隔开,形如:123,abc + * + * @author click33 + * @since 1.35.0 + */ +public class SaValue2Box { + + /** + * 第一个值 + */ + private Object value1; + + /** + * 第二个值 + */ + private Object value2; + + /** + * 直接提供两个值构建 + * @param value1 第一个值 + * @param value2 第二个值 + */ + public SaValue2Box(Object value1, Object value2) { + this.value1 = value1; + this.value2 = value2; + } + + /** + * 根据字符串构建,字符串形如:123,abc + * @param valueString 形如:123,abc + */ + public SaValue2Box(String valueString) { + if(valueString == null){ + return; + } + String[] split = valueString.split(","); + if(split.length == 0){ + // do nothing + } + else if(split.length == 1){ + this.value1 = split[0]; + } + else { + this.value1 = split[0]; + this.value2 = split[1]; + } + } + + /** + * 获取第一个值 + * @return 第一个值 + */ + public Object getValue1() { + return value1; + } + + /** + * 获取第二个值 + * @return 第二个值 + */ + public Object getValue2() { + return value2; + } + + /** + * 设置第一个值 + * @param value1 第一个值 + */ + public void setValue1(Object value1) { + this.value1 = value1; + } + + /** + * 设置第二个值 + * @param value2 第二个值 + */ + public void setValue2(Object value2) { + this.value2 = value2; + } + + /** + * 判断第一个值是否为 null 或者空字符串 + * @return / + */ + public boolean value1IsEmpty() { + return SaFoxUtil.isEmpty(value1); + } + + /** + * 判断第二个值是否为 null 或者空字符串 + * @return / + */ + public boolean value2IsEmpty() { + return SaFoxUtil.isEmpty(value2); + } + + /** + * 获取第一个值,并转化为 String 类型 + * @return / + */ + public String getValue1AsString() { + return value1 == null ? null : value1.toString(); + } + + /** + * 获取第二个值,并转化为 String 类型 + * @return / + */ + public String getValue2AsString() { + return value2 == null ? null : value2.toString(); + } + + /** + * 获取第一个值,并转化为 long 类型 + * @return / + */ + public long getValue1AsLong() { + return Long.parseLong(value1.toString()); + } + + /** + * 获取第二个值,并转化为 long 类型 + * @return / + */ + public long getValue2AsLong() { + return Long.parseLong(value2.toString()); + } + + /** + * 获取第一个值,并转化为 long 类型,值不存在则返回默认值 + * @return / + */ + public Long getValue1AsLong(Long defaultValue) { + // 这里如果改成三元表达式,会导致自动拆箱造成空指针异常,所以只能用 if-else + if(value1 == null){ + return defaultValue; + } + return Long.parseLong(value1.toString()); + } + + /** + * 获取第二个值,并转化为 long 类型,值不存在则返回默认值 + * @return / + */ + public Long getValue2AsLong(Long defaultValue) { + // 这里如果改成三元表达式,会导致自动拆箱造成空指针异常,所以只能用 if-else + if(value2 == null){ + return defaultValue; + } + return Long.parseLong(value2.toString()); + } + + /** + * 该容器是否为无值状态,即:value1 无值、value2 无值 + * @return / + */ + public boolean isNotValueState() { + return value1IsEmpty() && value2IsEmpty(); + } + + /** + * 该容器是否为单值状态,即:value1 有值、value2 == 无值 + * @return / + */ + public boolean isSingleValueState() { + return ! value1IsEmpty() && value2IsEmpty(); + } + + /** + * 该容器是否为双值状态,即:value2 有值 (在 value2 有值的情况下,即使 value1 无值,也视为双值状态) + * @return / + */ + public boolean isDoubleValueState() { + return ! value2IsEmpty(); + } + + /** + * 获取两个值的字符串形式,形如:123,abc + * + *

+ *
+     *     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
+     * 
+ * @return / + */ + @Override + public String toString() { + if(value1 == null && value2 == null) { + return null; + } + if(value1 != null && value2 == null) { + return value1.toString(); + } + return (value1 == null ? "" : value1.toString()) + "," + (value2 == null ? "" : value2.toString()); + } + +} \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/use/LoginAuthController.java b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/use/LoginAuthController.java index 6860ce75..6fcf96d2 100644 --- a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/use/LoginAuthController.java +++ b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/use/LoginAuthController.java @@ -111,7 +111,7 @@ public class LoginAuthController { System.out.println("当前登录账号的类型:" + info.getLoginType()); System.out.println("当前登录客户端的设备类型:" + info.getLoginDevice()); System.out.println("当前 Token 的剩余有效期:" + info.getTokenTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在 - System.out.println("当前 Token 的剩余临时有效期:" + info.getTokenActivityTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在 + System.out.println("当前 Token 距离被冻结还剩:" + info.getTokenActiveTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在 System.out.println("当前 Account-Session 的剩余有效期" + info.getSessionTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在 System.out.println("当前 Token-Session 的剩余有效期" + info.getTokenSessionTimeout()); // 单位:秒,-1代表永久有效,-2代表值不存在 diff --git a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpUserUtil.java b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpUserUtil.java index 9f526a9b..adb3b0a0 100644 --- a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpUserUtil.java +++ b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpUserUtil.java @@ -7,17 +7,15 @@ import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.SaTokenInfo; import cn.dev33.satoken.stp.StpLogic; -import org.springframework.stereotype.Component; import java.util.List; /** - * Sa-Token 权限认证工具类 (User版) + * Sa-Token 权限认证工具类 (User 版) * * @author click33 - * @since <= 1.34.0 + * @since 1.0.0 */ -@Component public class StpUserUtil { private StpUserUtil() {} @@ -25,7 +23,7 @@ public class StpUserUtil { /** * 多账号体系下的类型标识 */ - public static final String TYPE = "user"; + public static final String TYPE = "login"; /** * 底层使用的 StpLogic 对象 @@ -483,24 +481,24 @@ public class StpUserUtil { } - // ------------------- Activity-Timeout token 最低活跃度 验证相关 ------------------- - - /** - * 检查当前 token 是否已被冻结,如果是则抛出异常 - */ - public static void checkActivityTimeout() { - stpLogic.checkActivityTimeout(); - } + // ------------------- Active-Timeout token 最低活跃度 验证相关 ------------------- /** * 续签当前 token:(将 [最后操作时间] 更新为当前时间戳) *

* 请注意: 即使 token 已被冻结 也可续签成功, - * 如果此场景下需要提示续签失败,可在此之前调用 checkActivityTimeout() 强制检查是否冻结即可 + * 如果此场景下需要提示续签失败,可在此之前调用 checkActiveTimeout() 强制检查是否冻结即可 *

*/ - public static void updateLastActivityToNow() { - stpLogic.updateLastActivityToNow(); + public static void updateLastActiveToNow() { + stpLogic.updateLastActiveToNow(); + } + + /** + * 检查当前 token 是否已被冻结,如果是则抛出异常 + */ + public static void checkActiveTimeout() { + stpLogic.checkActiveTimeout(); } @@ -548,8 +546,8 @@ public class StpUserUtil { * * @return / */ - public static long getTokenActivityTimeout() { - return stpLogic.getTokenActivityTimeout(); + public static long getTokenActiveTimeout() { + return stpLogic.getTokenActiveTimeout(); } /** diff --git a/sa-token-demo/sa-token-demo-case/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-case/src/main/resources/application.yml index cb63067a..051ea222 100644 --- a/sa-token-demo/sa-token-demo-case/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-case/src/main/resources/application.yml @@ -2,22 +2,22 @@ server: port: 8081 -# sa-token配置 +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 - is-log: false + is-log: true spring: # redis配置 diff --git a/sa-token-demo/sa-token-demo-jwt/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-jwt/src/main/resources/application.yml index f0cf4189..e0a7d436 100644 --- a/sa-token-demo/sa-token-demo-jwt/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-jwt/src/main/resources/application.yml @@ -2,21 +2,21 @@ server: port: 8081 -# sa-token配置 +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid - # 是否打印操作日志 + # 是否输出操作日志 is-log: true # jwt秘钥 jwt-secret-key: asdasdasifhueuiwyurfewbfjsdafjk diff --git a/sa-token-demo/sa-token-demo-remember-me/server_project/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-remember-me/server_project/src/main/resources/application.yml index 424afda2..bf400e19 100644 --- a/sa-token-demo/sa-token-demo-remember-me/server_project/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-remember-me/server_project/src/main/resources/application.yml @@ -2,24 +2,22 @@ server: port: 80 -# sa-token配置 +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 禁止写入cookie - is-read-cookie: false - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) - is-share: false - # token风格 + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) + is-share: true + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 - is-log: false + is-log: true spring: # redis配置 diff --git a/sa-token-demo/sa-token-demo-solon/src/main/java/com/pj/test/TestController.java b/sa-token-demo/sa-token-demo-solon/src/main/java/com/pj/test/TestController.java index 50e75177..30f06694 100644 --- a/sa-token-demo/sa-token-demo-solon/src/main/java/com/pj/test/TestController.java +++ b/sa-token-demo/sa-token-demo-solon/src/main/java/com/pj/test/TestController.java @@ -159,8 +159,8 @@ public class TestController { public AjaxJson atCheck() { System.out.println("======================= 进入方法,测试注解鉴权接口 ========================= "); System.out.println("只有通过注解鉴权,才能进入此方法"); -// StpUtil.checkActivityTimeout(); -// StpUtil.updateLastActivityToNow(); +// StpUtil.checkActiveTimeout(); +// StpUtil.updateLastActiveToNow(); return AjaxJson.getSuccess(); } @@ -174,8 +174,8 @@ public class TestController { // [活动时间] 续签: http://localhost:8081/test/rene @Mapping("rene") public AjaxJson rene() { - StpUtil.checkActivityTimeout(); - StpUtil.updateLastActivityToNow(); + StpUtil.checkActiveTimeout(); + StpUtil.updateLastActiveToNow(); return AjaxJson.getSuccess("续签成功"); } diff --git a/sa-token-demo/sa-token-demo-solon/src/main/resources/app.yml b/sa-token-demo/sa-token-demo-solon/src/main/resources/app.yml index 74dd60ef..b196368c 100644 --- a/sa-token-demo/sa-token-demo-solon/src/main/resources/app.yml +++ b/sa-token-demo/sa-token-demo-solon/src/main/resources/app.yml @@ -2,19 +2,19 @@ server: port: 8081 -# sa-token配置 +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) - allow-concurrent-login: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) + is-concurrent: true + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 is-log: true diff --git a/sa-token-demo/sa-token-demo-springboot-redis/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-springboot-redis/src/main/resources/application.yml index 55685ecb..3a2d6f57 100644 --- a/sa-token-demo/sa-token-demo-springboot-redis/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-springboot-redis/src/main/resources/application.yml @@ -1,20 +1,20 @@ # 端口 server: port: 8081 - -# sa-token配置 + +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 is-log: true diff --git a/sa-token-demo/sa-token-demo-springboot-redisson/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-springboot-redisson/src/main/resources/application.yml index cbd12290..2e3219f5 100644 --- a/sa-token-demo/sa-token-demo-springboot-redisson/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-springboot-redisson/src/main/resources/application.yml @@ -2,21 +2,21 @@ server: port: 8081 -# sa-token配置 -sa-token: - # token名称 (同时也是cookie名称) +# sa-token 配置 +sa-token: + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid - # 是否输出操作日志 + # 是否输出操作日志 is-log: true spring: diff --git a/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java b/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java index cccdd95d..fe914cf0 100644 --- a/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java +++ b/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java @@ -160,8 +160,8 @@ public class TestController { public AjaxJson atCheck() { System.out.println("======================= 进入方法,测试注解鉴权接口 ========================= "); System.out.println("只有通过注解鉴权,才能进入此方法"); -// StpUtil.checkActivityTimeout(); -// StpUtil.updateLastActivityToNow(); +// StpUtil.checkActiveTimeout(); +// StpUtil.updateLastActiveToNow(); return AjaxJson.getSuccess(); } @@ -175,8 +175,8 @@ public class TestController { // [活动时间] 续签: http://localhost:8081/test/rene @RequestMapping("rene") public AjaxJson rene() { - StpUtil.checkActivityTimeout(); - StpUtil.updateLastActivityToNow(); + StpUtil.checkActiveTimeout(); + StpUtil.updateLastActiveToNow(); return AjaxJson.getSuccess("续签成功"); } diff --git a/sa-token-demo/sa-token-demo-springboot/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-springboot/src/main/resources/application.yml index cb63067a..2db5fb77 100644 --- a/sa-token-demo/sa-token-demo-springboot/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-springboot/src/main/resources/application.yml @@ -1,23 +1,23 @@ # 端口 server: port: 8081 - -# sa-token配置 + +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 - is-log: false + is-log: true spring: # redis配置 diff --git a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/resources/application.yml index 0ea7252c..1b1934e0 100644 --- a/sa-token-demo/sa-token-demo-springboot3-redis/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-springboot3-redis/src/main/resources/application.yml @@ -1,20 +1,20 @@ # 端口 server: port: 8081 - -# sa-token配置 + +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 is-log: true diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/StpUserUtil.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/StpUserUtil.java index 9f526a9b..adb3b0a0 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/StpUserUtil.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/StpUserUtil.java @@ -7,17 +7,15 @@ import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.SaTokenInfo; import cn.dev33.satoken.stp.StpLogic; -import org.springframework.stereotype.Component; import java.util.List; /** - * Sa-Token 权限认证工具类 (User版) + * Sa-Token 权限认证工具类 (User 版) * * @author click33 - * @since <= 1.34.0 + * @since 1.0.0 */ -@Component public class StpUserUtil { private StpUserUtil() {} @@ -25,7 +23,7 @@ public class StpUserUtil { /** * 多账号体系下的类型标识 */ - public static final String TYPE = "user"; + public static final String TYPE = "login"; /** * 底层使用的 StpLogic 对象 @@ -483,24 +481,24 @@ public class StpUserUtil { } - // ------------------- Activity-Timeout token 最低活跃度 验证相关 ------------------- - - /** - * 检查当前 token 是否已被冻结,如果是则抛出异常 - */ - public static void checkActivityTimeout() { - stpLogic.checkActivityTimeout(); - } + // ------------------- Active-Timeout token 最低活跃度 验证相关 ------------------- /** * 续签当前 token:(将 [最后操作时间] 更新为当前时间戳) *

* 请注意: 即使 token 已被冻结 也可续签成功, - * 如果此场景下需要提示续签失败,可在此之前调用 checkActivityTimeout() 强制检查是否冻结即可 + * 如果此场景下需要提示续签失败,可在此之前调用 checkActiveTimeout() 强制检查是否冻结即可 *

*/ - public static void updateLastActivityToNow() { - stpLogic.updateLastActivityToNow(); + public static void updateLastActiveToNow() { + stpLogic.updateLastActiveToNow(); + } + + /** + * 检查当前 token 是否已被冻结,如果是则抛出异常 + */ + public static void checkActiveTimeout() { + stpLogic.checkActiveTimeout(); } @@ -548,8 +546,8 @@ public class StpUserUtil { * * @return / */ - public static long getTokenActivityTimeout() { - return stpLogic.getTokenActivityTimeout(); + public static long getTokenActiveTimeout() { + return stpLogic.getTokenActiveTimeout(); } /** diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java index fe6b12d4..cf2c5ba4 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java @@ -1,11 +1,15 @@ package com.pj.test; +import cn.dev33.satoken.stp.SaLoginConfig; import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.util.Date; + /** * 测试专用Controller * @author click33 @@ -18,14 +22,15 @@ public class TestController { // 测试登录 ---- http://localhost:8081/test/login @RequestMapping("login") public SaResult login(@RequestParam(defaultValue = "10001") long id) { - StpUtil.login(id); + StpUtil.login(id, SaLoginConfig.setActiveTimeout(20)); return SaResult.ok("登录成功"); } - + // 测试 浏览器访问: http://localhost:8081/test/test @RequestMapping("test") public SaResult test() { - System.out.println("------------进来了"); + System.out.println("------------进来了 " + SaFoxUtil.formatDate(new Date())); + StpUtil.checkLogin(); // 返回 return SaResult.data(null); } 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 221cb0f1..33c83e8a 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 @@ -4,17 +4,17 @@ server: ############## Sa-Token 配置 (文档: https://sa-token.cc) ############## sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: 100000 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 is-log: true diff --git a/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/resources/application.yml index 3e644c7f..1828ff6a 100644 --- a/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-webflux-springboot3/src/main/resources/application.yml @@ -2,21 +2,21 @@ server: port: 8081 -# sa-token配置 +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid - # 日志 + # 是否输出操作日志 is-log: true spring: diff --git a/sa-token-demo/sa-token-demo-webflux/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-webflux/src/main/resources/application.yml index 3e644c7f..1828ff6a 100644 --- a/sa-token-demo/sa-token-demo-webflux/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-webflux/src/main/resources/application.yml @@ -2,21 +2,21 @@ server: port: 8081 -# sa-token配置 +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid - # 日志 + # 是否输出操作日志 is-log: true spring: diff --git a/sa-token-demo/sa-token-demo-websocket-spring/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-websocket-spring/src/main/resources/application.yml index cb63067a..2db5fb77 100644 --- a/sa-token-demo/sa-token-demo-websocket-spring/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-websocket-spring/src/main/resources/application.yml @@ -1,23 +1,23 @@ # 端口 server: port: 8081 - -# sa-token配置 + +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 - is-log: false + is-log: true spring: # redis配置 diff --git a/sa-token-demo/sa-token-demo-websocket/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-websocket/src/main/resources/application.yml index cb63067a..2db5fb77 100644 --- a/sa-token-demo/sa-token-demo-websocket/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-websocket/src/main/resources/application.yml @@ -1,23 +1,23 @@ # 端口 server: port: 8081 - -# sa-token配置 + +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 - is-log: false + is-log: true spring: # redis配置 diff --git a/sa-token-doc/api/stp-util.md b/sa-token-doc/api/stp-util.md index 1837df09..8395090f 100644 --- a/sa-token-doc/api/stp-util.md +++ b/sa-token-doc/api/stp-util.md @@ -90,12 +90,12 @@ StpUtil.getSessionBySessionId("xxxx-xxxx-xxxx"); // 获取指定key的Session, ### 6、Token有效期相关 ``` java -// 临时有效期 -StpUtil.getTokenActivityTimeout(); // 获取当前 token [临时过期] 剩余有效时间 (单位: 秒) -StpUtil.checkActivityTimeout(); // 检查当前token 是否已经[临时过期],如果已经过期则抛出异常 -StpUtil.updateLastActivityToNow(); // 续签当前token:(将 [最后操作时间] 更新为当前时间戳) +// Token 最低活跃频率 +StpUtil.getTokenActiveTimeout(); // 获取当前 token 距离被冻结还剩多少时间 (单位: 秒) +StpUtil.checkActiveTimeout(); // 检查当前token 是否已经被冻结,如果是则抛出异常 +StpUtil.updateLastActiveToNow(); // 续签当前token:(将 [最后操作时间] 更新为当前时间戳) -// 长久有效期 +// Token 有效期 StpUtil.getTokenTimeout(); // 获取当前登录者的 token 剩余有效时间 (单位: 秒) StpUtil.getSessionTimeout(); // 获取当前登录者的 Account-Session 剩余有效时间 (单位: 秒) StpUtil.getTokenSessionTimeout(); // 获取当前 Token-Session 剩余有效时间 (单位: 秒) diff --git a/sa-token-doc/fun/exception-code.md b/sa-token-doc/fun/exception-code.md index 3cfc33c8..0675dc1f 100644 --- a/sa-token-doc/fun/exception-code.md +++ b/sa-token-doc/fun/exception-code.md @@ -79,7 +79,7 @@ SaToken 中的所有异常都是继承于 `SaTokenException` 的,也就是说 | 11013 | Token已过期 | | 11014 | Token已被顶下线 | | 11015 | Token已被踢下线 | -| 11016 | Token已临时过期 | +| 11016 | Token已被冻结 | | 11031 | 在未集成 sa-token-jwt 插件时调用 getExtra() 抛出异常 | | 11041 | 缺少指定的角色 | | 11051 | 缺少指定的权限 | diff --git a/sa-token-doc/fun/token-info.md b/sa-token-doc/fun/token-info.md index ab31874b..68e69a5d 100644 --- a/sa-token-doc/fun/token-info.md +++ b/sa-token-doc/fun/token-info.md @@ -15,7 +15,7 @@ token信息Model: 用来描述一个token的常用参数 "tokenTimeout": 2591977, // token剩余有效期 (单位: 秒) "sessionTimeout": 2591977, // Account-Session剩余有效时间 (单位: 秒) "tokenSessionTimeout": -2, // Token-Session剩余有效时间 (单位: 秒) (-2表示系统中不存在这个缓存) - "tokenActivityTimeout": -1, // token剩余无操作有效时间 (单位: 秒) + "tokenActiveTimeout": -1, // token 距离被冻结还剩的时间 (单位: 秒) "loginDevice": "default-device" // 登录设备类型 }, } diff --git a/sa-token-doc/fun/token-timeout.md b/sa-token-doc/fun/token-timeout.md index e5397514..309110dd 100644 --- a/sa-token-doc/fun/token-timeout.md +++ b/sa-token-doc/fun/token-timeout.md @@ -2,7 +2,7 @@ -Sa-Token 提供两种 Token 自动过期策略,分别是 `timeout` 与 `activity-timeout`,配置方法如下: +Sa-Token 提供两种 Token 自动过期策略,分别是 `timeout` 与 `active-timeout`,配置方法如下: @@ -11,14 +11,14 @@ sa-token: # token 有效期(单位:秒),默认30天,-1代表永不过期 timeout: 2592000 # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 - activity-timeout: -1 + active-timeout: -1 ``` ``` properties # token 有效期(单位:秒),默认30天,-1代表永不过期 sa-token.timeout=2592000 # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 -sa-token.activity-timeout=-1 +sa-token.active-timeout=-1 ``` @@ -29,7 +29,7 @@ sa-token.activity-timeout=-1 > 2. 银行为你颁发一张储蓄卡(系统为你颁发一个Token),以后每次存取钱都要带上这张卡(后续每次访问系统都要提交 Token)。 > 3. 银行为这张卡设定两个过期时间: > - 第一个是 `timeout`,代表这张卡的长久有效期,就是指这张卡最长能用多久,假设 `timeout=3年`,那么3年后此卡将被银行删除,想要继续来银行办理业务必须重新办卡(Token 过期后想要访问系统必须重新登录)。 -> - 第二个就是 `activity-timeout`,代表这张卡的最低活跃频率限制,就是指这张卡必须每隔多久来银行一次,假设 `activity-timeout=1月` ,你如果超过1月不来办一次业务,银行就将你的卡冻结,列为长期不动户(Token 长期不访问系统,被冻结,但不会被删除)。 +> - 第二个就是 `active-timeout`,代表这张卡的最低活跃频率限制,就是指这张卡必须每隔多久来银行一次,假设 `active-timeout=1月` ,你如果超过1月不来办一次业务,银行就将你的卡冻结,列为长期不动户(Token 长期不访问系统,被冻结,但不会被删除)。 > 4. 两个过期策略可以单独配置,也可以同时配置,只要有其中一个有效期超出了范围,这张卡就会变得不可用(两个有效期只要有一个过期了,Token就无法成功访问系统了)。 下面是对两个过期策略的详细解释: @@ -40,33 +40,33 @@ sa-token.activity-timeout=-1 3. `timeout`的值配置为-1后,代表永久有效,不会过期。 -### activity-timeout -1. `activity-timeout`代表最低活跃频率,单位/秒,例如将其配置为 1800 (30分钟),代表用户如果30分钟无操作,则此Token会立即过期(被冻结,但不会删除掉)。 +### active-timeout +1. `active-timeout`代表最低活跃频率,单位/秒,例如将其配置为 1800 (30分钟),代表用户如果30分钟无操作,则此Token会立即过期(被冻结,但不会删除掉)。 2. 如果在30分钟内用户有操作,则会再次续签30分钟,用户如果一直操作则会一直续签,直到连续30分钟无操作,Token才会过期。 -3. `activity-timeout`的值配置为-1后,代表永久有效,不会过期,此时也无需频繁续签。 +3. `active-timeout`的值配置为-1后,代表永久有效,不会过期,此时也无需频繁续签。 -### 关于activity-timeout的续签 -如果`activity-timeout`配置了大于零的值,Sa-Token 会在登录时开始计时,在每次直接或间接调用`getLoginId()`时进行一次冻结检查与续签操作。 +### 关于active-timeout的续签 +如果`active-timeout`配置了大于零的值,Sa-Token 会在登录时开始计时,在每次直接或间接调用`getLoginId()`时进行一次冻结检查与续签操作。 此时会有两种情况: 1. 一种是会话无操作时间太长,Token已经被冻结,此时框架会抛出`NotLoginException`异常(场景值=-3), -2. 另一种则是会话在`activity-timeout`有效期内通过检查,此时Token可以成功续签 +2. 另一种则是会话在`active-timeout`有效期内通过检查,此时Token可以成功续签 -### 我可以手动续签 activity-timeout 吗? +### 我可以手动续签 active-timeout 吗? **可以!** 如果框架的自动续签算法无法满足您的业务需求,你可以进行手动续签,Sa-Token 提供两个API供你操作: -1. `StpUtil.checkActivityTimeout()`: 检查当前Token 是否已经被冻结,如果是则抛出异常 -2. `StpUtil.updateLastActivityToNow()`: 续签当前Token:(将 [最后操作时间] 更新为当前时间戳) +1. `StpUtil.checkActiveTimeout()`: 检查当前Token 是否已经被冻结,如果是则抛出异常 +2. `StpUtil.updateLastActiveToNow()`: 续签当前Token:(将 [最后操作时间] 更新为当前时间戳) 注意:在手动续签时,即使 Token 已经被冻结也可续签成功(解冻),如果此场景下需要提示续签失败,可采用先检查再续签的形式保证Token有效性 例如以下代码: ``` java // 先检查是否已被冻结 -StpUtil.checkActivityTimeout(); +StpUtil.checkActiveTimeout(); // 检查通过后继续续签 -StpUtil.updateLastActivityToNow(); +StpUtil.updateLastActiveToNow(); ``` 同时,你还可以关闭框架的自动续签(在配置文件中配置 `autoRenew=false` ),此时续签操作完全由开发者控制,框架不再自动进行任何续签操作 @@ -75,16 +75,16 @@ StpUtil.updateLastActivityToNow(); ``` java // 为指定 Token 续签 -StpUtil.stpLogic.updateLastActivityToNow(tokenValue); +StpUtil.stpLogic.updateLastActiveToNow(tokenValue); ``` -### timeout 与 activity-timeout 可以同时使用吗? +### timeout 与 active-timeout 可以同时使用吗? **可以同时使用!** 两者的认证逻辑彼此独立,互不干扰,可以同时使用。 -### StpUtil 类中哪些公开方法支持临时有效期自动续签 activity-timeout? +### StpUtil 类中哪些公开方法支持自动续签 active-timeout? > 直接或间接获取了当前用户id的方法 (间接调用过 StpLogic.getLoginId() 方法) | 包括但不限于这些: | diff --git a/sa-token-doc/more/common-action.md b/sa-token-doc/more/common-action.md index db92396f..b9b3a54c 100644 --- a/sa-token-doc/more/common-action.md +++ b/sa-token-doc/more/common-action.md @@ -73,18 +73,20 @@ SaFoxUtil.toList(... strs); // String 数组转集合 1、首先在项目根目录,创建一个配置文件:`sa-token.properties` -``` java -# token名称 (同时也是cookie名称) +``` properties +# token 名称 (同时也是 cookie 名称) tokenName=satoken -# token有效期,单位s 默认30天, -1代表永不过期 +# token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout=2592000 -# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 -activityTimeout=-1 -# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) =-1 +# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 +activeTimeout=-1 +# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) isConcurrent=true -# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) +# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) isShare=true -# token风格 +# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) +tokenStyle=uuid +# 是否输出操作日志 isLog=false ``` diff --git a/sa-token-doc/more/common-questions.md b/sa-token-doc/more/common-questions.md index 9dcb325e..1189b16c 100644 --- a/sa-token-doc/more/common-questions.md +++ b/sa-token-doc/more/common-questions.md @@ -88,7 +88,7 @@ Sa-Token 的部分 API 只能在 Web 上下文中才能调用,例如:`StpUti - 可能9:可能是多账号鉴权的关系,在多账号模式下,如果是 `StpUserUtil.login()` 颁发的token,你从 `StpUtil.checkLogin()` 进行校验,永远都是无效token,因为账号体系没对上。 **如果是:Token已过期:6ad93254-b286-4ec9-9997-4430b0341ca0** -- 可能1:前端提交的 token 临时过期(activity-timeout超时了,比如配置了 activity-timeout=120,但是超过了120秒没有访问接口)。 +- 可能1:前端提交的 token 已被冻结(active-timeout超时了,比如配置了 active-timeout=120,但是超过了120秒没有访问接口)。 - 可能2:集成jwt,而且使用的是 Mixin 或 Stateless 模式,而且token过期了(timeout超时了)。 **如果是:Token已被顶下线:6ad93254-b286-4ec9-9997-4430b0341ca0** diff --git a/sa-token-doc/more/noun-intro.md b/sa-token-doc/more/noun-intro.md index 8d85314c..22b85da9 100644 --- a/sa-token-doc/more/noun-intro.md +++ b/sa-token-doc/more/noun-intro.md @@ -18,7 +18,7 @@ Sa-Token 无意发明任何晦涩概念提升逼格,但在处理 issue 、Q群 #### 两种过期时间: - timeout:会话 Token 的长久有效期。 -- activity-timeout:会话的临时有效期。 +- active-timeout:会话 Token 的最低活跃频率。 两者的差别详见:[Token有效期详解](/fun/token-timeout) diff --git a/sa-token-doc/plugin/jwt-extend.md b/sa-token-doc/plugin/jwt-extend.md index 7aed51f9..84f534b8 100644 --- a/sa-token-doc/plugin/jwt-extend.md +++ b/sa-token-doc/plugin/jwt-extend.md @@ -150,7 +150,7 @@ eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbklkIjoiMTAwMDEiLCJybiI6IjZYYzgySzB | 角色认证 | 支持 | 支持 | 支持 | | 权限认证 | 支持 | 支持 | 支持 | | timeout 有效期 | 支持 | 支持 | 支持 | -| activity-timeout 有效期 | 支持 | 支持 | 不支持 | +| active-timeout 有效期 | 支持 | 支持 | 不支持 | | id反查Token | 支持 | 支持 | 不支持 | | 会话管理 | 支持 | 部分支持 | 不支持 | | 注解鉴权 | 支持 | 支持 | 支持 | diff --git a/sa-token-doc/start/example.md b/sa-token-doc/start/example.md index b5e267db..6be60871 100644 --- a/sa-token-doc/start/example.md +++ b/sa-token-doc/start/example.md @@ -57,18 +57,18 @@ server: sa-token: # token 名称(同时也是 cookie 名称) token-name: satoken - # token 有效期(单位:秒),默认30天,-1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 - activity-timeout: -1 - # 是否允许同一账号多地同时登录(为 true 时允许一起登录,为 false 时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token 风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid - # 是否输出操作日志 - is-log: false + # 是否输出操作日志 + is-log: true ``` @@ -78,20 +78,20 @@ server.port=8081 ############## Sa-Token 配置 (文档: https://sa-token.cc) ############## -# token名称(同时也是 cookie 名称) +# token 名称(同时也是 cookie 名称) sa-token.token-name=satoken -# token 有效期(单位:秒),默认30天,-1代表永不过期 +# token 有效期(单位:秒) 默认30天,-1 代表永久有效 sa-token.timeout=2592000 # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 -sa-token.activity-timeout=-1 -# 是否允许同一账号多地同时登录(为 true 时允许一起登录,为 false 时新登录挤掉旧登录) +sa-token.active-timeout=-1 +# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) sa-token.is-concurrent=true -# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token) +# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) sa-token.is-share=true -# token 风格 +# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) sa-token.token-style=uuid # 是否输出操作日志 -sa-token.is-log=false +sa-token.is-log=true ``` diff --git a/sa-token-doc/start/solon-example.md b/sa-token-doc/start/solon-example.md index a6a87e41..c31a989f 100644 --- a/sa-token-doc/start/solon-example.md +++ b/sa-token-doc/start/solon-example.md @@ -68,18 +68,18 @@ server: sa-token: # token 名称(同时也是 cookie 名称) token-name: satoken - # token 有效期(单位:秒),默认30天,-1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 - activity-timeout: -1 - # 是否允许同一账号多地同时登录(为 true 时允许一起登录,为 false 时新登录挤掉旧登录) + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token 风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 - is-log: false + is-log: true ``` @@ -89,20 +89,20 @@ server.port=8081 ############## Sa-Token 配置 (文档: https://sa-token.cc) ############## -# token名称(同时也是 cookie 名称) +# token 名称(同时也是 cookie 名称) sa-token.token-name=satoken -# token 有效期(单位:秒),默认30天,-1代表永不过期 +# token 有效期(单位:秒) 默认30天,-1 代表永久有效 sa-token.timeout=2592000 # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 -sa-token.activity-timeout=-1 -# 是否允许同一账号多地同时登录(为 true 时允许一起登录,为 false 时新登录挤掉旧登录) +sa-token.active-timeout=-1 +# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) sa-token.is-concurrent=true -# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token) +# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) sa-token.is-share=true -# token 风格 +# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) sa-token.token-style=uuid # 是否输出操作日志 -sa-token.is-log=false +sa-token.is-log=true ``` diff --git a/sa-token-doc/use/config.md b/sa-token-doc/use/config.md index a4828da3..1d6a0956 100644 --- a/sa-token-doc/use/config.md +++ b/sa-token-doc/use/config.md @@ -14,38 +14,38 @@ sa-token: # token 名称(同时也是 cookie 名称) token-name: satoken - # token 有效期(单位:秒),默认30天,-1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 - activity-timeout: -1 - # 是否允许同一账号多地同时登录(为 true 时允许一起登录,为 false 时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token 风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid - # 是否输出操作日志 - is-log: false + # 是否输出操作日志 + is-log: true ``` ``` properties ############## Sa-Token 配置 (文档: https://sa-token.cc) ############## -# token名称(同时也是 cookie 名称) +# token 名称(同时也是 cookie 名称) sa-token.token-name=satoken -# token 有效期(单位:秒),默认30天,-1代表永不过期 +# token 有效期(单位:秒) 默认30天,-1 代表永久有效 sa-token.timeout=2592000 # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 -sa-token.activity-timeout=-1 -# 是否允许同一账号多地同时登录(为 true 时允许一起登录,为 false 时新登录挤掉旧登录) +sa-token.active-timeout=-1 +# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) sa-token.is-concurrent=true -# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token) +# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) sa-token.is-share=true -# token 风格 +# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) sa-token.token-style=uuid # 是否输出操作日志 -sa-token.is-log=false +sa-token.is-log=true ``` @@ -70,7 +70,7 @@ public class SaTokenConfigure { SaTokenConfig config = new SaTokenConfig(); config.setTokenName("satoken"); // token 名称(同时也是 cookie 名称) config.setTimeout(30 * 24 * 60 * 60); // token 有效期(单位:秒),默认30天,-1代表永不过期 - config.setActivityTimeout(-1); // token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + config.setActiveTimeout(-1); // token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 config.setIsConcurrent(true); // 是否允许同一账号多地同时登录(为 true 时允许一起登录,为 false 时新登录挤掉旧登录) config.setIsShare(true); // 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token) config.setTokenStyle("uuid"); // token 风格 @@ -92,7 +92,7 @@ public class SaTokenConfigure { public void configSaToken(SaTokenConfig config) { config.setTokenName("satoken"); // token 名称(同时也是 cookie 名称) config.setTimeout(30 * 24 * 60 * 60); // token 有效期(单位:秒),默认30天,-1代表永不过期 - config.setActivityTimeout(-1); // token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + config.setActiveTimeout(-1); // token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 config.setIsConcurrent(true); // 是否允许同一账号多地同时登录(为 true 时允许一起登录,为 false 时新登录挤掉旧登录) config.setIsShare(true); // 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token) config.setTokenStyle("uuid"); // token 风格 @@ -116,7 +116,7 @@ public class SaTokenConfigure { | :-------- | :-------- | :-------- | :-------- | | tokenName | String | satoken | Token 名称 (同时也是 Cookie 名称、数据持久化前缀) | | timeout | long | 2592000 | Token 有效期(单位:秒),默认30天,-1代表永不过期 [参考:token有效期详解](/fun/token-timeout) | -| activityTimeout | long | -1 | Token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结(例如可以设置为1800代表30分钟内无操作就过期) [参考:token有效期详解](/fun/token-timeout) | +| activeTimeout | long | -1 | Token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结(例如可以设置为1800代表30分钟内无操作就冻结) [参考:token有效期详解](/fun/token-timeout) | | isConcurrent | Boolean | true | 是否允许同一账号并发登录 (为 true 时允许一起登录,为 false 时新登录挤掉旧登录) | | isShare | Boolean | true | 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token) | | maxLoginCount | int | 12 | 同一账号最大登录数量,-1代表不限 (只有在 `isConcurrent=true`,`isShare=false` 时此配置才有效),[详解](/use/config?id=配置项详解:maxlogincount) | diff --git a/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForMixin.java b/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForMixin.java index 5966e5be..38077af3 100644 --- a/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForMixin.java +++ b/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForMixin.java @@ -89,7 +89,7 @@ public class StpLogicJwtForMixin extends StpLogic { info.tokenTimeout = getTokenTimeout(); info.sessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE; info.tokenSessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE; - info.tokenActivityTimeout = SaTokenDao.NOT_VALUE_EXPIRE; + info.tokenActiveTimeout = SaTokenDao.NOT_VALUE_EXPIRE; info.loginDevice = getLoginDevice(); return info; } diff --git a/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForStateless.java b/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForStateless.java index a9140983..daf5e4c6 100644 --- a/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForStateless.java +++ b/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForStateless.java @@ -91,7 +91,7 @@ public class StpLogicJwtForStateless extends StpLogic { info.tokenTimeout = getTokenTimeout(); info.sessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE; info.tokenSessionTimeout = SaTokenDao.NOT_VALUE_EXPIRE; - info.tokenActivityTimeout = SaTokenDao.NOT_VALUE_EXPIRE; + info.tokenActiveTimeout = SaTokenDao.NOT_VALUE_EXPIRE; info.loginDevice = getLoginDevice(); return info; } diff --git a/sa-token-starter/sa-token-jboot-plugin/src/test/java/cn/dev33/satoken/jboot/test/AtteStartListener.java b/sa-token-starter/sa-token-jboot-plugin/src/test/java/cn/dev33/satoken/jboot/test/AtteStartListener.java index a53bd731..073dccee 100644 --- a/sa-token-starter/sa-token-jboot-plugin/src/test/java/cn/dev33/satoken/jboot/test/AtteStartListener.java +++ b/sa-token-starter/sa-token-jboot-plugin/src/test/java/cn/dev33/satoken/jboot/test/AtteStartListener.java @@ -39,7 +39,7 @@ public class AtteStartListener implements JbootAppListener { SaTokenConfig saTokenConfig = new SaTokenConfig(); saTokenConfig.setTokenStyle(SaTokenConsts.TOKEN_STYLE_SIMPLE_UUID); saTokenConfig.setTimeout(60*60*4); //登录有效时间4小时 - saTokenConfig.setActivityTimeout(30*60); //半小时无操作过期处理 + saTokenConfig.setActiveTimeout(30*60); //半小时无操作就冻结 token saTokenConfig.setIsShare(false); saTokenConfig.setTokenName("token"); //更换satoken的名称 saTokenConfig.setCookie(new SaCookieConfig().setHttpOnly(true)); //开启cookies的httponly属性 diff --git a/sa-token-starter/sa-token-jfinal-plugin/src/test/java/cn/dev33/satoken/jfinal/test/Config.java b/sa-token-starter/sa-token-jfinal-plugin/src/test/java/cn/dev33/satoken/jfinal/test/Config.java index 8fe79e8e..527e5821 100644 --- a/sa-token-starter/sa-token-jfinal-plugin/src/test/java/cn/dev33/satoken/jfinal/test/Config.java +++ b/sa-token-starter/sa-token-jfinal-plugin/src/test/java/cn/dev33/satoken/jfinal/test/Config.java @@ -38,7 +38,7 @@ public class Config extends JFinalConfig { SaTokenConfig saTokenConfig = new SaTokenConfig(); saTokenConfig.setTokenStyle(SaTokenConsts.TOKEN_STYLE_SIMPLE_UUID); saTokenConfig.setTimeout(60*60*4); //登录有效时间4小时 - saTokenConfig.setActivityTimeout(30*60); //半小时无操作过期处理 + saTokenConfig.setActiveTimeout(30*60); //半小时无操作就冻结 token saTokenConfig.setIsShare(false); saTokenConfig.setTokenName("token"); //更改satoken的cookies名称 SaCookieConfig saCookieConfig = new SaCookieConfig(); diff --git a/sa-token-starter/sa-token-solon-plugin/src/test/resources/app.yml b/sa-token-starter/sa-token-solon-plugin/src/test/resources/app.yml index 5dd15890..06aa42b1 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/test/resources/app.yml +++ b/sa-token-starter/sa-token-solon-plugin/src/test/resources/app.yml @@ -1,21 +1,21 @@ -# sa-token配置 +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) - allow-concurrent-login: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) + is-concurrent: true + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid - # 是否输出操作日志 - is-log: false + # 是否输出操作日志 + is-log: true sa-token-dao: #名字可以随意取 diff --git a/sa-token-test/sa-token-jwt-test/src/test/resources/application.yml b/sa-token-test/sa-token-jwt-test/src/test/resources/application.yml index 0f148e62..b2cd002e 100644 --- a/sa-token-test/sa-token-jwt-test/src/test/resources/application.yml +++ b/sa-token-test/sa-token-jwt-test/src/test/resources/application.yml @@ -2,19 +2,19 @@ server: port: 8081 -# sa-token配置 +# sa-token 配置 sa-token: - # token名称 (同时也是cookie名称) + # token 名称 (同时也是 cookie 名称) token-name: satoken - # token有效期,单位s 默认30天, -1代表永不过期 + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 - # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 - activity-timeout: -1 - # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true - # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: true - # token风格 + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # jwt秘钥 jwt-secret-key: asdasdasifhueuiwyurfewbfjsdafjk diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java index 7848a86b..a99ccb3b 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/config/SaTokenConfigTest.java @@ -41,8 +41,8 @@ public class SaTokenConfigTest { config.setTimeout(100204); Assertions.assertEquals(config.getTimeout(), 100204); - config.setActivityTimeout(1804); - Assertions.assertEquals(config.getActivityTimeout(), 1804); + config.setActiveTimeout(1804); + Assertions.assertEquals(config.getActiveTimeout(), 1804); config.setIsConcurrent(false); Assertions.assertEquals(config.getIsConcurrent(), false); @@ -111,7 +111,7 @@ public class SaTokenConfigTest { SaTokenConfig config = SaTokenConfigFactory.createConfig("sa-token2.properties"); Assertions.assertEquals(config.getTokenName(), "use-token"); Assertions.assertEquals(config.getTimeout(), 9000); - Assertions.assertEquals(config.getActivityTimeout(), 240); + Assertions.assertEquals(config.getActiveTimeout(), 240); Assertions.assertEquals(config.getIsConcurrent(), false); Assertions.assertEquals(config.getIsShare(), false); Assertions.assertEquals(config.getIsLog(), true); diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/stp/TokenInfoTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/stp/TokenInfoTest.java index 3a076a11..f0956425 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/stp/TokenInfoTest.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/stp/TokenInfoTest.java @@ -45,7 +45,7 @@ public class TokenInfoTest { info.setTokenTimeout(1800); info.setSessionTimeout(120); info.setTokenSessionTimeout(1800); - info.setTokenActivityTimeout(120); + info.setTokenActiveTimeout(120); info.setLoginDevice("PC"); info.setTag("xxx"); @@ -57,7 +57,7 @@ public class TokenInfoTest { Assertions.assertEquals(info.getTokenTimeout(), 1800); Assertions.assertEquals(info.getSessionTimeout(), 120); Assertions.assertEquals(info.getTokenSessionTimeout(), 1800); - Assertions.assertEquals(info.getTokenActivityTimeout(), 120); + Assertions.assertEquals(info.getTokenActiveTimeout(), 120); Assertions.assertEquals(info.getLoginDevice(), "PC"); Assertions.assertEquals(info.getTag(), "xxx"); diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/springboot/BasicsTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/springboot/BasicsTest.java index f0bdb8d6..fa365f1e 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/springboot/BasicsTest.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/springboot/BasicsTest.java @@ -75,7 +75,7 @@ public class BasicsTest { @BeforeAll public static void beforeClass() { System.out.println("\n\n------------------------ 基础测试 star ..."); - SaManager.getConfig().setActivityTimeout(180); + SaManager.getConfig().setActiveTimeout(180); } // 结束 @@ -710,20 +710,20 @@ public class BasicsTest { Assertions.assertEquals(tokenSession.get("code"), "123456"); } - // 测试,临时过期 + // 测试,token 最低活跃频率 @Test - public void testActivityTimeout() { + public void testActiveTimeout() { // 登录 StpUtil.login(10001); Assertions.assertNotNull(StpUtil.getTokenValue()); // 默认跟随全局 timeout - StpUtil.updateLastActivityToNow(); - long activityTimeout = StpUtil.getTokenActivityTimeout(); - Assertions.assertTrue(activityTimeout <=180 || activityTimeout >=179); + StpUtil.updateLastActiveToNow(); + long activeTimeout = StpUtil.getTokenActiveTimeout(); + Assertions.assertTrue(activeTimeout <=180 || activeTimeout >=179); // 不会抛出异常 - Assertions.assertDoesNotThrow(() -> StpUtil.checkActivityTimeout()); + Assertions.assertDoesNotThrow(() -> StpUtil.checkActiveTimeout()); } // 测试,上下文 API diff --git a/sa-token-test/sa-token-springboot-test/src/test/resources/sa-token2.properties b/sa-token-test/sa-token-springboot-test/src/test/resources/sa-token2.properties index 929ff96e..e65a57f6 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/resources/sa-token2.properties +++ b/sa-token-test/sa-token-springboot-test/src/test/resources/sa-token2.properties @@ -1,12 +1,12 @@ -# token名称 (同时也是cookie名称) +# token 名称 (同时也是 cookie 名称) tokenName=use-token -# token有效期,单位s 默认30天, -1代表永不过期 +# token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout=9000 -# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 -activityTimeout=240 -# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) =-1 +# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 +activeTimeout=240 +# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) isConcurrent=false -# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) +# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) isShare=false -# token风格 -isLog=true +# 是否输出操作日志 +isLog=true \ No newline at end of file