From 4d2eb4e94bde5e8ed87190eec516018ebf14baeb Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Wed, 19 Mar 2025 11:03:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20SaTokenConfig=20=E6=96=B0=E5=A2=9E=20re?= =?UTF-8?q?placedRange=E3=80=81overflowLogoutMode=E3=80=81logoutRange?= =?UTF-8?q?=E3=80=81isLogoutKeepFreezeOps=E3=80=81isLogoutKeepTokenSession?= =?UTF-8?q?=20=E9=85=8D=E7=BD=AE=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev33/satoken/config/SaTokenConfig.java | 143 +++++++++++++++++- .../stp/parameter/SaLoginParameter.java | 31 ++-- .../stp/parameter/SaLogoutParameter.java | 60 +++++--- sa-token-demo/sa-token-demo-test/pom.xml | 2 +- .../main/java/com/pj/test/TestController.java | 10 +- sa-token-doc/up/login-parameter.md | 6 +- sa-token-doc/use/config.md | 5 + 7 files changed, 211 insertions(+), 46 deletions(-) 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 ec197731..1c4ea749 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,9 @@ */ package cn.dev33.satoken.config; +import cn.dev33.satoken.stp.parameter.enums.SaLogoutMode; +import cn.dev33.satoken.stp.parameter.enums.SaLogoutRange; +import cn.dev33.satoken.stp.parameter.enums.SaReplacedRange; import cn.dev33.satoken.util.SaFoxUtil; import java.io.Serializable; @@ -63,11 +66,21 @@ public class SaTokenConfig implements Serializable { */ private Boolean isShare = false; + /** + * 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端, ALL_DEVICE_TYPE=所有设备类型端) + */ + private SaReplacedRange replacedRange = SaReplacedRange.CURR_DEVICE_TYPE; + /** * 同一账号最大登录数量,-1代表不限 (只有在 isConcurrent=true, isShare=false 时此配置项才有意义) */ private int maxLoginCount = 12; + /** + * 溢出 maxLoginCount 的客户端,将以何种方式注销下线 (LOGOUT=注销下线, KICKOUT=踢人下线, REPLACED=顶人下线) + */ + private SaLogoutMode overflowLogoutMode = SaLogoutMode.LOGOUT; + /** * 在每次创建 token 时的最高循环次数,用于保证 token 唯一性(-1=不循环尝试,直接使用) */ @@ -98,6 +111,23 @@ public class SaTokenConfig implements Serializable { */ private Boolean isWriteHeader = false; + /** + * 注销范围 (TOKEN=只注销当前 token 的会话,ACCOUNT=注销当前 token 指向的 loginId 其所有客户端会话) + *
(此参数只在调用 StpUtil.logout() 时有效) + */ + private SaLogoutRange logoutRange = SaLogoutRange.TOKEN; + + /** + * 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API) + *
(此参数只在调用 StpUtil.[logout/kickout/replaced]ByTokenValue("token") 时有效) + */ + private Boolean isLogoutKeepFreezeOps = false; + + /** + * 在注销 token 后,是否保留其对应的 Token-Session + */ + private Boolean isLogoutKeepTokenSession = false; + /** * token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) */ @@ -669,7 +699,107 @@ public class SaTokenConfig implements Serializable { this.checkSameToken = checkSameToken; return this; } - + + /** + * 获取 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端 ALL_DEVICE_TYPE=所有设备类型端) + * + * @return / + */ + public SaReplacedRange getReplacedRange() { + return this.replacedRange; + } + + /** + * 设置 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端 ALL_DEVICE_TYPE=所有设备类型端) + * + * @param replacedRange / + * @return 对象自身 + */ + public SaTokenConfig setReplacedRange(SaReplacedRange replacedRange) { + this.replacedRange = replacedRange; + return this; + } + + /** + * 获取 溢出 maxLoginCount 的客户端,将以何种方式注销下线 (LOGOUT=注销下线, KICKOUT=踢人下线, REPLACED=顶人下线) + * + * @return / + */ + public SaLogoutMode getOverflowLogoutMode() { + return this.overflowLogoutMode; + } + + /** + * 设置 溢出 maxLoginCount 的客户端,将以何种方式注销下线 (LOGOUT=注销下线, KICKOUT=踢人下线, REPLACED=顶人下线) + * + * @param overflowLogoutMode / + * @return 对象自身 + */ + public SaTokenConfig setOverflowLogoutMode(SaLogoutMode overflowLogoutMode) { + this.overflowLogoutMode = overflowLogoutMode; + return this; + } + + /** + * 获取 注销范围 (TOKEN=只注销当前 token 的会话,ACCOUNT=注销当前 token 指向的 loginId 其所有客户端会话)
(此参数只在调用 StpUtil.logout() 时有效) + * + * @return / + */ + public SaLogoutRange getLogoutRange() { + return this.logoutRange; + } + + /** + * 设置 注销范围 (TOKEN=只注销当前 token 的会话,ACCOUNT=注销当前 token 指向的 loginId 其所有客户端会话)
(此参数只在调用 StpUtil.logout() 时有效) + * + * @param logoutRange / + * @return 对象自身 + */ + public SaTokenConfig setLogoutRange(SaLogoutRange logoutRange) { + this.logoutRange = logoutRange; + return this; + } + + /** + * 获取 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API)
(此参数只在调用 StpUtil.[logoutkickoutreplaced]ByTokenValue("token") 时有效) + * + * @return isLogoutKeepFreezeOps / + */ + public Boolean getIsLogoutKeepFreezeOps() { + return this.isLogoutKeepFreezeOps; + } + + /** + * 设置 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API)
(此参数只在调用 StpUtil.[logoutkickoutreplaced]ByTokenValue("token") 时有效) + * + * @param isLogoutKeepFreezeOps / + * @return 对象自身 + */ + public SaTokenConfig setIsLogoutKeepFreezeOps(Boolean isLogoutKeepFreezeOps) { + this.isLogoutKeepFreezeOps = isLogoutKeepFreezeOps; + return this; + } + + /** + * 获取 在注销 token 后,是否保留其对应的 Token-Session + * + * @return isLogoutKeepTokenSession / + */ + public Boolean getIsLogoutKeepTokenSession() { + return this.isLogoutKeepTokenSession; + } + + /** + * 设置 在注销 token 后,是否保留其对应的 Token-Session + * + * @param isLogoutKeepTokenSession / + * @return 对象自身 + */ + public SaTokenConfig setIsLogoutKeepTokenSession(Boolean isLogoutKeepTokenSession) { + this.isLogoutKeepTokenSession = isLogoutKeepTokenSession; + return this; + } + /** * @return Cookie 全局配置对象 */ @@ -721,6 +851,8 @@ public class SaTokenConfig implements Serializable { this.signMany = signMany; return this; } + + @Override public String toString() { return "SaTokenConfig [" @@ -728,15 +860,20 @@ public class SaTokenConfig implements Serializable { + ", timeout=" + timeout + ", activeTimeout=" + activeTimeout + ", dynamicActiveTimeout=" + dynamicActiveTimeout - + ", isConcurrent=" + isConcurrent - + ", isShare=" + isShare + + ", isConcurrent=" + isConcurrent + + ", isShare=" + isShare + + ", replacedRange=" + replacedRange + ", maxLoginCount=" + maxLoginCount + + ", overflowLogoutMode=" + overflowLogoutMode + ", maxTryTimes=" + maxTryTimes + ", isReadBody=" + isReadBody + ", isReadHeader=" + isReadHeader + ", isReadCookie=" + isReadCookie + ", isLastingCookie=" + isLastingCookie + ", isWriteHeader=" + isWriteHeader + + ", logoutRange=" + logoutRange + + ", isLogoutKeepFreezeOps=" + isLogoutKeepFreezeOps + + ", isLogoutKeepTokenSession=" + isLogoutKeepTokenSession + ", tokenStyle=" + tokenStyle + ", dataRefreshPeriod=" + dataRefreshPeriod + ", tokenSessionCheckLogin=" + tokenSessionCheckLogin diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLoginParameter.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLoginParameter.java index f3f83032..2ca7fb31 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLoginParameter.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLoginParameter.java @@ -50,16 +50,6 @@ public class SaLoginParameter { */ private String deviceId; - /** - * 顶人下线的范围 - */ - private SaReplacedRange replacedRange = SaReplacedRange.CURR_DEVICE_TYPE; - - /** - * 溢出 maxLoginCount 的客户端,将以何种方式注销下线 - */ - private SaLogoutMode overflowLogoutMode = SaLogoutMode.LOGOUT; - /** * 扩展信息(只在 jwt 模式下生效) */ @@ -118,6 +108,16 @@ public class SaLoginParameter { */ private Boolean isWriteHeader; + /** + * 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端, ALL_DEVICE_TYPE=所有设备类型端) + */ + private SaReplacedRange replacedRange; + + /** + * 溢出 maxLoginCount 的客户端,将以何种方式注销下线 (LOGOUT=注销下线, KICKOUT=踢人下线, REPLACED=顶人下线) + */ + private SaLogoutMode overflowLogoutMode; + // ------ 附加方法 @@ -143,6 +143,8 @@ public class SaLoginParameter { this.maxTryTimes = config.getMaxTryTimes(); this.isLastingCookie = config.getIsLastingCookie(); this.isWriteHeader = config.getIsWriteHeader(); + this.replacedRange = config.getReplacedRange(); + this.overflowLogoutMode = config.getOverflowLogoutMode(); return this; } @@ -287,7 +289,7 @@ public class SaLoginParameter { } /** - * 获取 顶人下线的范围 + * 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端, ALL_DEVICE_TYPE=所有设备类型端) * * @return replacedMode 顶人下线的范围 */ @@ -296,7 +298,7 @@ public class SaLoginParameter { } /** - * 设置 顶人下线的范围 + * 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端, ALL_DEVICE_TYPE=所有设备类型端) * * @param replacedRange / * @return 对象自身 @@ -307,7 +309,7 @@ public class SaLoginParameter { } /** - * 获取 溢出 maxLoginCount 的客户端,将以何种方式注销下线 + * 获取 溢出 maxLoginCount 的客户端,将以何种方式注销下线 (LOGOUT=注销下线, KICKOUT=踢人下线, REPLACED=顶人下线) * * @return overflowLogoutMode / */ @@ -316,7 +318,7 @@ public class SaLoginParameter { } /** - * 设置 溢出 maxLoginCount 的客户端,将以何种方式注销下线 + * 设置 溢出 maxLoginCount 的客户端,将以何种方式注销下线 (LOGOUT=注销下线, KICKOUT=踢人下线, REPLACED=顶人下线) * * @param overflowLogoutMode / * @return 对象自身 @@ -325,6 +327,7 @@ public class SaLoginParameter { this.overflowLogoutMode = overflowLogoutMode; return this; } + /** * @return 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在) */ diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLogoutParameter.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLogoutParameter.java index 0b627d4f..2ab93961 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLogoutParameter.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLogoutParameter.java @@ -33,31 +33,37 @@ import cn.dev33.satoken.stp.parameter.enums.SaLogoutRange; */ public class SaLogoutParameter { - /** - * 是否保留 Token-Session - */ - private Boolean isKeepTokenSession = false; + // --------- 单独参数 /** - * 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API) - * (此参数只在调用 StpUtil.[logout/kickout/replaced]ByTokenValue("xxxxxxxxxxxxxxxxxxx", new SaLogoutParameter()) 时有效) - */ - private Boolean isKeepFreezeOps = false; - - /** - * 设备类型 (如果不指定,则默认注销所有客户端) + * 需要注销的设备类型 (如果不指定,则默认注销所有客户端) */ private String deviceType; /** - * 注销类型 + * 注销类型 (LOGOUT=注销下线、KICKOUT=踢人下线,REPLACED=顶人下线) */ private SaLogoutMode mode = SaLogoutMode.LOGOUT; + + // --------- 覆盖性参数 + /** - * 注销范围 (此参数只在调用 StpUtil.logout(new SaLogoutParameter()) 时有效) + * 注销范围 (TOKEN=只注销当前 token 的会话,ACCOUNT=注销当前 token 指向的 loginId 其所有客户端会话) + *
(此参数只在调用 StpUtil.logout() 时有效) */ - private SaLogoutRange range = SaLogoutRange.TOKEN; + private SaLogoutRange range; + + /** + * 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API) + *
(此参数只在调用 StpUtil.[logout/kickout/replaced]ByTokenValue("token") 时有效) + */ + private Boolean isKeepFreezeOps; + + /** + * 在注销 token 后,是否保留其对应的 Token-Session + */ + private Boolean isKeepTokenSession; // ------ 附加方法 @@ -76,6 +82,9 @@ public class SaLogoutParameter { * @return 对象自身 */ public SaLogoutParameter setDefaultValues(SaTokenConfig config) { + this.range = config.getLogoutRange(); + this.isKeepFreezeOps = config.getIsLogoutKeepFreezeOps(); + this.isKeepTokenSession = config.getIsLogoutKeepTokenSession(); return this; } @@ -92,14 +101,14 @@ public class SaLogoutParameter { // ---------------- get set /** - * @return 是否保留 Token-Session + * @return 在注销 token 后,是否保留其对应的 Token-Session */ public Boolean getIsKeepTokenSession() { return isKeepTokenSession; } /** - * @param isKeepTokenSession 是否保留 Token-Session + * @param isKeepTokenSession 在注销 token 后,是否保留其对应的 Token-Session * * @return 对象自身 */ @@ -110,7 +119,7 @@ public class SaLogoutParameter { /** * 获取 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API) - * (此参数只在调用 StpUtil.[logout/kickout/replaced]ByTokenValue("xxxxxxxxxxxxxxxxxxx", new SaLogoutParameter()) 时有效) + *
(此参数只在调用 StpUtil.[logout/kickout/replaced]ByTokenValue("token") 时有效) * * @return / */ @@ -120,7 +129,7 @@ public class SaLogoutParameter { /** * 设置 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API) - * (此参数只在调用 StpUtil.[logout/kickout/replaced]ByTokenValue("xxxxxxxxxxxxxxxxxxx", new SaLogoutParameter()) 时有效) + *
(此参数只在调用 StpUtil.[logout/kickout/replaced]ByTokenValue("token") 时有效) * * @param isKeepFreezeOps / * @return 对象自身 @@ -129,8 +138,9 @@ public class SaLogoutParameter { this.isKeepFreezeOps = isKeepFreezeOps; return this; } + /** - * 获取 设备类型 (如果不指定,则默认注销所有客户端) + * 需要注销的设备类型 (如果不指定,则默认注销所有客户端) * * @return deviceType / */ @@ -139,7 +149,7 @@ public class SaLogoutParameter { } /** - * 设置 设备类型 (如果不指定,则默认注销所有客户端) + * 需要注销的设备类型 (如果不指定,则默认注销所有客户端) * * @param deviceType / * @return / @@ -150,7 +160,7 @@ public class SaLogoutParameter { } /** - * 获取 注销类型 + * 注销类型 (LOGOUT=注销下线、KICKOUT=踢人下线,REPLACED=顶人下线) * * @return logoutMode 注销类型 */ @@ -159,7 +169,7 @@ public class SaLogoutParameter { } /** - * 设置 注销类型 + * 注销类型 (LOGOUT=注销下线、KICKOUT=踢人下线,REPLACED=顶人下线) * * @param mode 注销类型 * @return / @@ -170,7 +180,8 @@ public class SaLogoutParameter { } /** - * 获取 注销范围 (此参数只在调用 StpUtil.logout(new SaLogoutParameter()) 时有效) + * 注销范围 (TOKEN=只注销当前 token 的会话,ACCOUNT=注销当前 token 指向的 loginId 其所有客户端会话) + *
(此参数只在调用 StpUtil.logout() 时有效) * * @return / */ @@ -179,7 +190,8 @@ public class SaLogoutParameter { } /** - * 设置 注销范围 (此参数只在调用 StpUtil.logout(new SaLogoutParameter()) 时有效) + * 注销范围 (TOKEN=只注销当前 token 的会话,ACCOUNT=注销当前 token 指向的 loginId 其所有客户端会话) + *
(此参数只在调用 StpUtil.logout() 时有效) * * @param range / * @return / diff --git a/sa-token-demo/sa-token-demo-test/pom.xml b/sa-token-demo/sa-token-demo-test/pom.xml index b0a5dba5..69f55a49 100644 --- a/sa-token-demo/sa-token-demo-test/pom.xml +++ b/sa-token-demo/sa-token-demo-test/pom.xml @@ -54,7 +54,7 @@ ${sa-token.version} --> - + cn.dev33 sa-token-redis-template 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 81f1fba6..d369c8b7 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 @@ -4,8 +4,8 @@ import cn.dev33.satoken.annotation.SaCheckHttpDigest; import cn.dev33.satoken.annotation.SaCheckSign; import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.spring.SpringMVCUtil; -import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaResult; import org.springframework.web.bind.annotation.RequestMapping; @@ -36,6 +36,7 @@ public class TestController { .setTerminalExtra("loginIp", "127.0.0.1") .setTerminalExtra("loginTime", SaFoxUtil.formatDate(new Date())) ); + StpUtil.getTokenSession(); return SaResult.ok("登录成功"); } @@ -81,4 +82,11 @@ public class TestController { return SaResult.data(null); } + // 测试注销 浏览器访问: http://localhost:8081/test/logout + @RequestMapping("logout") + public SaResult logout() { + StpUtil.logout(); + return SaResult.data(null); + } + } diff --git a/sa-token-doc/up/login-parameter.md b/sa-token-doc/up/login-parameter.md index 88cd8925..2de71a2e 100644 --- a/sa-token-doc/up/login-parameter.md +++ b/sa-token-doc/up/login-parameter.md @@ -46,14 +46,14 @@ StpUtil.login(10001, new SaLoginParameter() // 当前客户端注销 StpUtil.logout(new SaLogoutParameter() // 注销范围: TOKEN=只注销当前 token 的会话,ACCOUNT=注销当前 token 指向的 loginId 其所有客户端会话 - // 此参数只在调用 StpUtil.logout(new SaLogoutParameter()) 时有效 + // 此参数只在调用 StpUtil.logout() 时有效 .setRange(SaLogoutRange.TOKEN) ); // 指定 token 注销 StpUtil.logoutByTokenValue("xxxxxxxxxxxxxxxxxxxxxxx", new SaLogoutParameter() // 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API)(默认 false) - // 此参数只在调用 StpUtil.[logout/kickout/replaced]ByTokenValue("token", new SaLogoutParameter()) 时有效 + // 此参数只在调用 StpUtil.[logout/kickout/replaced]ByTokenValue("token") 时有效 .setIsKeepFreezeOps(false) // 是否保留此 token 的 Token-Session 对象(默认 false) .setIsKeepTokenSession(true) @@ -67,6 +67,6 @@ StpUtil.logout(10001, new SaLogoutParameter() ); ``` - +以上大部分参数在未指定时将使用全局配置作为默认值。 diff --git a/sa-token-doc/use/config.md b/sa-token-doc/use/config.md index 72a4b6a7..afe8a2c1 100644 --- a/sa-token-doc/use/config.md +++ b/sa-token-doc/use/config.md @@ -122,13 +122,18 @@ public class SaTokenConfigure { | dynamicActiveTimeout | Boolean | false | 是否启用动态 activeTimeout 功能,如不需要请设置为 false,节省缓存请求次数 | | isConcurrent | Boolean | true | 是否允许同一账号并发登录 (为 true 时允许一起登录,为 false 时新登录挤掉旧登录) | | isShare | Boolean | false | 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token,login 时提供了 Extra 数据后,即使配置了为 true 也不能复用旧 Token,必须创建新 Token) | +| replacedRange | SaReplacedRange | CURR_DEVICE_TYPE | 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端, ALL_DEVICE_TYPE=所有设备类型端) | | maxLoginCount | int | 12 | 同一账号最大登录数量,-1代表不限 (只有在 `isConcurrent=true`,`isShare=false` 时此配置才有效),[详解](/use/config?id=配置项详解:maxlogincount) | +| overflowLogoutMode | SaLogoutMode | LOGOUT | 溢出 maxLoginCount 的客户端,将以何种方式注销下线 (LOGOUT=注销下线, KICKOUT=踢人下线, REPLACED=顶人下线) | | maxTryTimes | int | 12 | 在每次创建 Token 时的最高循环次数,用于保证 Token 唯一性(-1=不循环重试,直接使用) | | isReadBody | Boolean | true | 是否尝试从 请求体 里读取 Token | | isReadHeader | Boolean | true | 是否尝试从 header 里读取 Token | | isReadCookie | Boolean | true | 是否尝试从 cookie 里读取 Token,此值为 false 后,`StpUtil.login(id)` 登录时也不会再往前端注入Cookie | | isLastingCookie | Boolean | true | 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在) | | isWriteHeader | Boolean | false | 是否在登录后将 Token 写入到响应头 | +| logoutRange | SaLogoutRange | TOKEN | 注销范围 (TOKEN=只注销当前 token 的会话,ACCOUNT=注销当前 token 指向的 loginId 其所有客户端会话) (此参数只在调用 StpUtil.logout() 时有效) | +| isLogoutKeepFreezeOps | Boolean | false | 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API) (此参数只在调用 StpUtil.[logout/kickout/replaced]ByTokenValue("token") 时有效) | +| isLogoutKeepTokenSession | Boolean | false | 在注销 token 后,是否保留其对应的 Token-Session | | tokenStyle | String | uuid | token风格, [参考:自定义Token风格](/up/token-style) | | dataRefreshPeriod | int | 30 | 默认数据持久组件实现类中,每次清理过期数据间隔的时间 (单位: 秒) ,默认值30秒,设置为-1代表不启动定时清理 | | tokenSessionCheckLogin | Boolean | true | 获取 `Token-Session` 时是否必须登录 (如果配置为true,会在每次获取 `Token-Session` 时校验是否登录),[详解](/use/config?id=配置项详解:tokenSessionCheckLogin) |