mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-04-05 17:37:53 +08:00
新增登录时动态指定 active-timeout 能力
This commit is contained in:
parent
48ba6da91a
commit
814a64907a
sa-token-core/src/main/java/cn/dev33/satoken
annotation
config
listener
stp
util
sa-token-demo
sa-token-demo-case/src/main
sa-token-demo-jwt/src/main/resources
sa-token-demo-remember-me/server_project/src/main/resources
sa-token-demo-solon/src/main
sa-token-demo-springboot-redis/src/main/resources
sa-token-demo-springboot-redisson/src/main/resources
sa-token-demo-springboot/src/main
sa-token-demo-springboot3-redis/src/main/resources
sa-token-demo-test/src/main
sa-token-demo-webflux-springboot3/src/main/resources
sa-token-demo-webflux/src/main/resources
sa-token-demo-websocket-spring/src/main/resources
sa-token-demo-websocket/src/main/resources
sa-token-doc
api
fun
more
plugin
start
use
sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt
sa-token-starter
sa-token-jboot-plugin/src/test/java/cn/dev33/satoken/jboot/test
sa-token-jfinal-plugin/src/test/java/cn/dev33/satoken/jfinal/test
sa-token-solon-plugin/src/test/resources
sa-token-test
sa-token-jwt-test/src/test/resources
sa-token-springboot-test/src/test
java/cn/dev33/satoken
resources
@ -25,7 +25,7 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* <p> 可标注在方法、类上(效果等同于标注在此类的所有方法上)
|
||||
*
|
||||
* @author kong
|
||||
* @author click33
|
||||
* @since 1.10.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
@ -25,7 +25,7 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* <p> 可标注在方法、类上(效果等同于标注在此类的所有方法上)
|
||||
*
|
||||
* @author kong
|
||||
* @author click33
|
||||
* @since 1.35.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 对象自身
|
||||
|
@ -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" // 登录设备类型
|
||||
* }
|
||||
* </pre>
|
||||
@ -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
|
||||
+ "]";
|
||||
}
|
||||
|
||||
|
@ -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<String, Object> 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:(将 [最后操作时间] 更新为当前时间戳)
|
||||
* <h2>
|
||||
* 请注意: 即使 token 已被冻结 也可续签成功,
|
||||
* 如果此场景下需要提示续签失败,可在此之前调用 checkActiveTimeout() 强制检查是否冻结即可
|
||||
* </h2>
|
||||
*/
|
||||
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:(将 [最后操作时间] 更新为当前时间戳)
|
||||
* <h2>
|
||||
* 请注意: 即使 token 已被冻结 也可续签成功,
|
||||
* 如果此场景下需要提示续签失败,可在此之前调用 checkActivityTimeout() 强制检查是否冻结即可
|
||||
* </h2>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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:(将 [最后操作时间] 更新为当前时间戳)
|
||||
* <h2>
|
||||
* 请注意: 即使 token 已被冻结 也可续签成功,
|
||||
* 如果此场景下需要提示续签失败,可在此之前调用 checkActivityTimeout() 强制检查是否冻结即可
|
||||
* 如果此场景下需要提示续签失败,可在此之前调用 checkActiveTimeout() 强制检查是否冻结即可
|
||||
* </h2>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
* <br><br>
|
||||
* <pre>
|
||||
* 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
|
||||
* </pre>
|
||||
* @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());
|
||||
}
|
||||
|
||||
}
|
@ -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代表值不存在
|
||||
|
||||
|
@ -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:(将 [最后操作时间] 更新为当前时间戳)
|
||||
* <h2>
|
||||
* 请注意: 即使 token 已被冻结 也可续签成功,
|
||||
* 如果此场景下需要提示续签失败,可在此之前调用 checkActivityTimeout() 强制检查是否冻结即可
|
||||
* 如果此场景下需要提示续签失败,可在此之前调用 checkActiveTimeout() 强制检查是否冻结即可
|
||||
* </h2>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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配置
|
||||
|
@ -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
|
||||
|
@ -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配置
|
||||
|
@ -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("续签成功");
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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("续签成功");
|
||||
}
|
||||
|
||||
|
@ -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配置
|
||||
|
@ -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
|
||||
|
@ -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:(将 [最后操作时间] 更新为当前时间戳)
|
||||
* <h2>
|
||||
* 请注意: 即使 token 已被冻结 也可续签成功,
|
||||
* 如果此场景下需要提示续签失败,可在此之前调用 checkActivityTimeout() 强制检查是否冻结即可
|
||||
* 如果此场景下需要提示续签失败,可在此之前调用 checkActiveTimeout() 强制检查是否冻结即可
|
||||
* </h2>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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配置
|
||||
|
@ -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配置
|
||||
|
@ -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 剩余有效时间 (单位: 秒)
|
||||
|
@ -79,7 +79,7 @@ SaToken 中的所有异常都是继承于 `SaTokenException` 的,也就是说
|
||||
| 11013 | Token已过期 |
|
||||
| 11014 | Token已被顶下线 |
|
||||
| 11015 | Token已被踢下线 |
|
||||
| 11016 | Token已临时过期 |
|
||||
| 11016 | Token已被冻结 |
|
||||
| 11031 | 在未集成 sa-token-jwt 插件时调用 getExtra() 抛出异常 |
|
||||
| 11041 | 缺少指定的角色 |
|
||||
| 11051 | 缺少指定的权限 |
|
||||
|
@ -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" // 登录设备类型
|
||||
},
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<!-- 本篇介绍Token有效期的详细用法 -->
|
||||
|
||||
Sa-Token 提供两种 Token 自动过期策略,分别是 `timeout` 与 `activity-timeout`,配置方法如下:
|
||||
Sa-Token 提供两种 Token 自动过期策略,分别是 `timeout` 与 `active-timeout`,配置方法如下:
|
||||
|
||||
<!---------------------------- tabs:start ---------------------------->
|
||||
<!------------- tab:yaml 风格 ------------->
|
||||
@ -11,14 +11,14 @@ sa-token:
|
||||
# token 有效期(单位:秒),默认30天,-1代表永不过期
|
||||
timeout: 2592000
|
||||
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
|
||||
activity-timeout: -1
|
||||
active-timeout: -1
|
||||
```
|
||||
<!------------- tab:properties 风格 ------------->
|
||||
``` properties
|
||||
# token 有效期(单位:秒),默认30天,-1代表永不过期
|
||||
sa-token.timeout=2592000
|
||||
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
|
||||
sa-token.activity-timeout=-1
|
||||
sa-token.active-timeout=-1
|
||||
```
|
||||
<!---------------------------- tabs:end ---------------------------->
|
||||
|
||||
@ -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() 方法)
|
||||
|
||||
| 包括但不限于这些: |
|
||||
|
@ -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
|
||||
```
|
||||
|
||||
|
@ -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**
|
||||
|
@ -18,7 +18,7 @@ Sa-Token 无意发明任何晦涩概念提升逼格,但在处理 issue 、Q群
|
||||
|
||||
#### 两种过期时间:
|
||||
- timeout:会话 Token 的长久有效期。
|
||||
- activity-timeout:会话的临时有效期。
|
||||
- active-timeout:会话 Token 的最低活跃频率。
|
||||
|
||||
两者的差别详见:[Token有效期详解](/fun/token-timeout)
|
||||
|
||||
|
@ -150,7 +150,7 @@ eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbklkIjoiMTAwMDEiLCJybiI6IjZYYzgySzB
|
||||
| 角色认证 | 支持 | 支持 | 支持 |
|
||||
| 权限认证 | 支持 | 支持 | 支持 |
|
||||
| timeout 有效期 | 支持 | 支持 | 支持 |
|
||||
| activity-timeout 有效期 | 支持 | 支持 | 不支持 |
|
||||
| active-timeout 有效期 | 支持 | 支持 | 不支持 |
|
||||
| id反查Token | 支持 | 支持 | 不支持 |
|
||||
| 会话管理 | 支持 | 部分支持 | 不支持 |
|
||||
| 注解鉴权 | 支持 | 支持 | 支持 |
|
||||
|
@ -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
|
||||
```
|
||||
|
||||
<!------------- tab:application.properties 风格 ------------->
|
||||
@ -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
|
||||
```
|
||||
|
||||
<!---------------------------- tabs:end ---------------------------->
|
||||
|
@ -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
|
||||
```
|
||||
|
||||
<!------------- tab:app.properties 风格 ------------->
|
||||
@ -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
|
||||
```
|
||||
|
||||
<!---------------------------- tabs:end ---------------------------->
|
||||
|
@ -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
|
||||
```
|
||||
|
||||
<!------------- tab:properties 风格 ------------->
|
||||
``` 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
|
||||
```
|
||||
|
||||
<!---------------------------- tabs:end ---------------------------->
|
||||
@ -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) |
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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属性
|
||||
|
@ -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();
|
||||
|
@ -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: #名字可以随意取
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user