mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-21 02:57:56 +08:00
v1.9.0 新特性 同端互斥登录
This commit is contained in:
@@ -31,18 +31,18 @@ public class SaTokenInfo {
|
|||||||
/** token专属session剩余有效时间 (单位: 秒) */
|
/** token专属session剩余有效时间 (单位: 秒) */
|
||||||
public long tokenSessionTimeout;
|
public long tokenSessionTimeout;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* token剩余无操作有效时间
|
* token剩余无操作有效时间
|
||||||
*/
|
*/
|
||||||
public long tokenActivityTimeout;
|
public long tokenActivityTimeout;
|
||||||
|
|
||||||
|
/** 当前登录设备 */
|
||||||
|
public String loginDevice;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return tokenName token名称
|
* @return tokenName
|
||||||
*/
|
*/
|
||||||
public String getTokenName() {
|
public String getTokenName() {
|
||||||
return tokenName;
|
return tokenName;
|
||||||
@@ -50,11 +50,9 @@ public class SaTokenInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tokenName 要设置的 tokenName
|
* @param tokenName 要设置的 tokenName
|
||||||
* @return 对象自身
|
|
||||||
*/
|
*/
|
||||||
public SaTokenInfo setTokenName(String tokenName) {
|
public void setTokenName(String tokenName) {
|
||||||
this.tokenName = tokenName;
|
this.tokenName = tokenName;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,11 +64,9 @@ public class SaTokenInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tokenValue 要设置的 tokenValue
|
* @param tokenValue 要设置的 tokenValue
|
||||||
* @return 对象自身
|
|
||||||
*/
|
*/
|
||||||
public SaTokenInfo setTokenValue(String tokenValue) {
|
public void setTokenValue(String tokenValue) {
|
||||||
this.tokenValue = tokenValue;
|
this.tokenValue = tokenValue;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,11 +78,9 @@ public class SaTokenInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param isLogin 要设置的 isLogin
|
* @param isLogin 要设置的 isLogin
|
||||||
* @return 对象自身
|
|
||||||
*/
|
*/
|
||||||
public SaTokenInfo setIsLogin(Boolean isLogin) {
|
public void setIsLogin(Boolean isLogin) {
|
||||||
this.isLogin = isLogin;
|
this.isLogin = isLogin;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,11 +92,9 @@ public class SaTokenInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param loginId 要设置的 loginId
|
* @param loginId 要设置的 loginId
|
||||||
* @return 对象自身
|
|
||||||
*/
|
*/
|
||||||
public SaTokenInfo setLoginId(Object loginId) {
|
public void setLoginId(Object loginId) {
|
||||||
this.loginId = loginId;
|
this.loginId = loginId;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,11 +106,9 @@ public class SaTokenInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param loginKey 要设置的 loginKey
|
* @param loginKey 要设置的 loginKey
|
||||||
* @return 对象自身
|
|
||||||
*/
|
*/
|
||||||
public SaTokenInfo setLoginKey(String loginKey) {
|
public void setLoginKey(String loginKey) {
|
||||||
this.loginKey = loginKey;
|
this.loginKey = loginKey;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,11 +120,9 @@ public class SaTokenInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tokenTimeout 要设置的 tokenTimeout
|
* @param tokenTimeout 要设置的 tokenTimeout
|
||||||
* @return 对象自身
|
|
||||||
*/
|
*/
|
||||||
public SaTokenInfo setTokenTimeout(long tokenTimeout) {
|
public void setTokenTimeout(long tokenTimeout) {
|
||||||
this.tokenTimeout = tokenTimeout;
|
this.tokenTimeout = tokenTimeout;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -146,11 +134,9 @@ public class SaTokenInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param sessionTimeout 要设置的 sessionTimeout
|
* @param sessionTimeout 要设置的 sessionTimeout
|
||||||
* @return 对象自身
|
|
||||||
*/
|
*/
|
||||||
public SaTokenInfo setSessionTimeout(long sessionTimeout) {
|
public void setSessionTimeout(long sessionTimeout) {
|
||||||
this.sessionTimeout = sessionTimeout;
|
this.sessionTimeout = sessionTimeout;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,11 +148,9 @@ public class SaTokenInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tokenSessionTimeout 要设置的 tokenSessionTimeout
|
* @param tokenSessionTimeout 要设置的 tokenSessionTimeout
|
||||||
* @return 对象自身
|
|
||||||
*/
|
*/
|
||||||
public SaTokenInfo setTokenSessionTimeout(long tokenSessionTimeout) {
|
public void setTokenSessionTimeout(long tokenSessionTimeout) {
|
||||||
this.tokenSessionTimeout = tokenSessionTimeout;
|
this.tokenSessionTimeout = tokenSessionTimeout;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -178,11 +162,23 @@ public class SaTokenInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tokenActivityTimeout 要设置的 tokenActivityTimeout
|
* @param tokenActivityTimeout 要设置的 tokenActivityTimeout
|
||||||
* @return 对象自身
|
|
||||||
*/
|
*/
|
||||||
public SaTokenInfo setTokenActivityTimeout(long tokenActivityTimeout) {
|
public void setTokenActivityTimeout(long tokenActivityTimeout) {
|
||||||
this.tokenActivityTimeout = tokenActivityTimeout;
|
this.tokenActivityTimeout = tokenActivityTimeout;
|
||||||
return this;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return loginDevice
|
||||||
|
*/
|
||||||
|
public String getLoginDevice() {
|
||||||
|
return loginDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param loginDevice 要设置的 loginDevice
|
||||||
|
*/
|
||||||
|
public void setLoginDevice(String loginDevice) {
|
||||||
|
this.loginDevice = loginDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -193,7 +189,7 @@ public class SaTokenInfo {
|
|||||||
return "SaTokenInfo [tokenName=" + tokenName + ", tokenValue=" + tokenValue + ", isLogin=" + isLogin
|
return "SaTokenInfo [tokenName=" + tokenName + ", tokenValue=" + tokenValue + ", isLogin=" + isLogin
|
||||||
+ ", loginId=" + loginId + ", loginKey=" + loginKey + ", tokenTimeout=" + tokenTimeout
|
+ ", loginId=" + loginId + ", loginKey=" + loginKey + ", tokenTimeout=" + tokenTimeout
|
||||||
+ ", sessionTimeout=" + sessionTimeout + ", tokenSessionTimeout=" + tokenSessionTimeout
|
+ ", sessionTimeout=" + sessionTimeout + ", tokenSessionTimeout=" + tokenSessionTimeout
|
||||||
+ ", tokenActivityTimeout=" + tokenActivityTimeout + "]";
|
+ ", tokenActivityTimeout=" + tokenActivityTimeout + ", loginDevice=" + loginDevice + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -209,5 +205,4 @@ public class SaTokenInfo {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -119,6 +119,7 @@ public class StpLogic {
|
|||||||
info.sessionTimeout = getSessionTimeout();
|
info.sessionTimeout = getSessionTimeout();
|
||||||
info.tokenSessionTimeout = getTokenSessionTimeout();
|
info.tokenSessionTimeout = getTokenSessionTimeout();
|
||||||
info.tokenActivityTimeout = getTokenActivityTimeout();
|
info.tokenActivityTimeout = getTokenActivityTimeout();
|
||||||
|
info.loginDevice = getLoginDevice();
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,12 +131,24 @@ public class StpLogic {
|
|||||||
* @param loginId 登录id,建议的类型:(long | int | String)
|
* @param loginId 登录id,建议的类型:(long | int | String)
|
||||||
*/
|
*/
|
||||||
public void setLoginId(Object loginId) {
|
public void setLoginId(Object loginId) {
|
||||||
|
setLoginId(loginId, SaTokenConsts.DEFAULT_LOGIN_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
// ------ 0、如果当前会话已经登录上了此LoginId,则立即返回
|
/**
|
||||||
|
* 在当前会话上登录id
|
||||||
|
* @param loginId 登录id,建议的类型:(long | int | String)
|
||||||
|
* @param device 设备标识
|
||||||
|
*/
|
||||||
|
public void setLoginId(Object loginId, String device) {
|
||||||
|
|
||||||
|
// ------ 0、如果当前会话已经登录上了此LoginId,且登录设备相同,则立即返回
|
||||||
Object loggedId = getLoginIdDefaultNull();
|
Object loggedId = getLoginIdDefaultNull();
|
||||||
if(loggedId != null && loggedId.toString().equals(loginId.toString())) {
|
if(loggedId != null && loggedId.toString().equals(loginId.toString())) {
|
||||||
|
String loggedDevice = getLoginDevice();
|
||||||
|
if(loggedDevice != null && loggedDevice.equals(device)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------ 1、获取相应对象
|
// ------ 1、获取相应对象
|
||||||
HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest();
|
HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest();
|
||||||
@@ -148,18 +161,20 @@ public class StpLogic {
|
|||||||
if(config.getAllowConcurrentLogin() == true) {
|
if(config.getAllowConcurrentLogin() == true) {
|
||||||
// 如果配置为共享token, 则尝试从session签名记录里取出token
|
// 如果配置为共享token, 则尝试从session签名记录里取出token
|
||||||
if(config.getIsShare() == true) {
|
if(config.getIsShare() == true) {
|
||||||
tokenValue = getTokenValueByLoginId(loginId);
|
tokenValue = getTokenValueByLoginId(loginId, device);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// --- 如果不允许并发登录
|
// --- 如果不允许并发登录
|
||||||
// 如果此时[id-session]不为null,说明此账号在其他地正在登录,现在需要先把其它地的token标记为被顶下线
|
// 如果此时[id-session]不为null,说明此账号在其他地正在登录,现在需要先把其它地的同设备token标记为被顶下线
|
||||||
SaSession session = getSessionByLoginId(loginId, false);
|
SaSession session = getSessionByLoginId(loginId, false);
|
||||||
if(session != null) {
|
if(session != null) {
|
||||||
List<String> tokenValueList = getTokenValueListByLoginId(loginId);
|
List<TokenSign> tokenSignList = session.getTokenSignList();
|
||||||
for (String token : tokenValueList) {
|
for (TokenSign tokenSign : tokenSignList) {
|
||||||
dao.updateValue(getKeyTokenValue(token), NotLoginException.BE_REPLACED); // 1. 将此token 标记为已顶替
|
if(tokenSign.getDevice().equals(device)) {
|
||||||
clearLastActivity(token); // 2. 清理掉[token-最后操作时间]
|
dao.updateValue(getKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED); // 1. 将此token 标记为已顶替
|
||||||
session.removeTokenSign(token); // 3. 清理账号session上的token签名
|
clearLastActivity(tokenSign.getValue()); // 2. 清理掉[token-最后操作时间]
|
||||||
|
session.removeTokenSign(tokenSign.getValue()); // 3. 清理账号session上的token签名记录
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,7 +191,7 @@ public class StpLogic {
|
|||||||
dao.updateSessionTimeout(session.getId(), config.getTimeout());
|
dao.updateSessionTimeout(session.getId(), config.getTimeout());
|
||||||
}
|
}
|
||||||
// 在session上记录token签名
|
// 在session上记录token签名
|
||||||
session.addTokenSign(new TokenSign(tokenValue, SaTokenConsts.DEFAULT_LOGIN_DEVICE));
|
session.addTokenSign(new TokenSign(tokenValue, device));
|
||||||
|
|
||||||
// ------ 4. 持久化其它数据
|
// ------ 4. 持久化其它数据
|
||||||
dao.setValue(getKeyTokenValue(tokenValue), String.valueOf(loginId), config.getTimeout()); // token -> uid
|
dao.setValue(getKeyTokenValue(tokenValue), String.valueOf(loginId), config.getTimeout()); // token -> uid
|
||||||
@@ -187,6 +202,7 @@ public class StpLogic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前会话注销登录
|
* 当前会话注销登录
|
||||||
*/
|
*/
|
||||||
@@ -203,6 +219,7 @@ public class StpLogic {
|
|||||||
logoutByTokenValue(tokenValue);
|
logoutByTokenValue(tokenValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指定token的会话注销登录
|
* 指定token的会话注销登录
|
||||||
* @param tokenValue 指定token
|
* @param tokenValue 指定token
|
||||||
@@ -229,12 +246,23 @@ public class StpLogic {
|
|||||||
session.logoutByTokenSignCountToZero();
|
session.logoutByTokenSignCountToZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指定loginId的会话注销登录(踢人下线)
|
* 指定loginId的会话注销登录(踢人下线)
|
||||||
* <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-2
|
* <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-2
|
||||||
* @param loginId 账号id
|
* @param loginId 账号id
|
||||||
*/
|
*/
|
||||||
public void logoutByLoginId(Object loginId) {
|
public void logoutByLoginId(Object loginId) {
|
||||||
|
logoutByLoginId(loginId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定loginId指定设备的会话注销登录(踢人下线)
|
||||||
|
* <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-2
|
||||||
|
* @param loginId 账号id
|
||||||
|
* @param device 设备标识 (填null代表所有注销设备)
|
||||||
|
*/
|
||||||
|
public void logoutByLoginId(Object loginId, String device) {
|
||||||
// 先获取这个账号的[id-session], 如果为null,则不执行任何操作
|
// 先获取这个账号的[id-session], 如果为null,则不执行任何操作
|
||||||
SaSession session = getSessionByLoginId(loginId);
|
SaSession session = getSessionByLoginId(loginId);
|
||||||
if(session == null) {
|
if(session == null) {
|
||||||
@@ -244,6 +272,7 @@ public class StpLogic {
|
|||||||
// 循环token签名列表,开始删除相关信息
|
// 循环token签名列表,开始删除相关信息
|
||||||
List<TokenSign> tokenSignList = session.getTokenSignList();
|
List<TokenSign> tokenSignList = session.getTokenSignList();
|
||||||
for (TokenSign tokenSign : tokenSignList) {
|
for (TokenSign tokenSign : tokenSignList) {
|
||||||
|
if(device == null || tokenSign.getDevice().equals(device)) {
|
||||||
// 1. 获取token
|
// 1. 获取token
|
||||||
String tokenValue = tokenSign.getValue();
|
String tokenValue = tokenSign.getValue();
|
||||||
// 2. 清理掉[token-最后操作时间]
|
// 2. 清理掉[token-最后操作时间]
|
||||||
@@ -253,6 +282,7 @@ public class StpLogic {
|
|||||||
// 4. 清理账号session上的token签名
|
// 4. 清理账号session上的token签名
|
||||||
session.removeTokenSign(tokenValue);
|
session.removeTokenSign(tokenValue);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// 尝试注销session
|
// 尝试注销session
|
||||||
session.logoutByTokenSignCountToZero();
|
session.logoutByTokenSignCountToZero();
|
||||||
}
|
}
|
||||||
@@ -269,6 +299,7 @@ public class StpLogic {
|
|||||||
return getLoginIdDefaultNull() != null;
|
return getLoginIdDefaultNull() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检验当前会话是否已经登录,如未登录,则抛出异常
|
* 检验当前会话是否已经登录,如未登录,则抛出异常
|
||||||
*/
|
*/
|
||||||
@@ -276,6 +307,7 @@ public class StpLogic {
|
|||||||
getLoginId();
|
getLoginId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前会话账号id, 如果未登录,则抛出异常
|
* 获取当前会话账号id, 如果未登录,则抛出异常
|
||||||
* @return 账号id
|
* @return 账号id
|
||||||
@@ -310,6 +342,7 @@ public class StpLogic {
|
|||||||
return loginId;
|
return loginId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前会话登录id, 如果未登录,则返回默认值
|
* 获取当前会话登录id, 如果未登录,则返回默认值
|
||||||
* @param <T> 返回类型
|
* @param <T> 返回类型
|
||||||
@@ -336,6 +369,7 @@ public class StpLogic {
|
|||||||
return (T)loginId;
|
return (T)loginId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前会话登录id, 如果未登录,则返回null
|
* 获取当前会话登录id, 如果未登录,则返回null
|
||||||
* @return 账号id
|
* @return 账号id
|
||||||
@@ -359,6 +393,7 @@ public class StpLogic {
|
|||||||
return loginId;
|
return loginId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前会话登录id, 并转换为String
|
* 获取当前会话登录id, 并转换为String
|
||||||
* @return 账号id
|
* @return 账号id
|
||||||
@@ -367,6 +402,7 @@ public class StpLogic {
|
|||||||
return String.valueOf(getLoginId());
|
return String.valueOf(getLoginId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前会话登录id, 并转换为int
|
* 获取当前会话登录id, 并转换为int
|
||||||
* @return 账号id
|
* @return 账号id
|
||||||
@@ -379,6 +415,7 @@ public class StpLogic {
|
|||||||
return Integer.valueOf(String.valueOf(getLoginId()));
|
return Integer.valueOf(String.valueOf(getLoginId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前会话登录id, 并转换为long
|
* 获取当前会话登录id, 并转换为long
|
||||||
* @return 账号id
|
* @return 账号id
|
||||||
@@ -391,6 +428,7 @@ public class StpLogic {
|
|||||||
return Long.valueOf(String.valueOf(getLoginId()));
|
return Long.valueOf(String.valueOf(getLoginId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定token对应的登录id,如果未登录,则返回 null
|
* 获取指定token对应的登录id,如果未登录,则返回 null
|
||||||
* @param tokenValue token
|
* @param tokenValue token
|
||||||
@@ -424,6 +462,7 @@ public class StpLogic {
|
|||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定loginId的session, 如果session尚未创建,isCreate=是否新建并返回
|
* 获取指定loginId的session, 如果session尚未创建,isCreate=是否新建并返回
|
||||||
* @param loginId 账号id
|
* @param loginId 账号id
|
||||||
@@ -434,6 +473,7 @@ public class StpLogic {
|
|||||||
return getSessionBySessionId(getKeySession(loginId), isCreate);
|
return getSessionBySessionId(getKeySession(loginId), isCreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定loginId的session,如果session尚未创建,则新建并返回
|
* 获取指定loginId的session,如果session尚未创建,则新建并返回
|
||||||
* @param loginId 账号id
|
* @param loginId 账号id
|
||||||
@@ -443,6 +483,7 @@ public class StpLogic {
|
|||||||
return getSessionByLoginId(loginId, true);
|
return getSessionByLoginId(loginId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前会话的session, 如果session尚未创建,isCreate=是否新建并返回
|
* 获取当前会话的session, 如果session尚未创建,isCreate=是否新建并返回
|
||||||
* @param isCreate 是否新建
|
* @param isCreate 是否新建
|
||||||
@@ -452,6 +493,7 @@ public class StpLogic {
|
|||||||
return getSessionByLoginId(getLoginId(), isCreate);
|
return getSessionByLoginId(getLoginId(), isCreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前会话的session,如果session尚未创建,则新建并返回
|
* 获取当前会话的session,如果session尚未创建,则新建并返回
|
||||||
* @return 当前会话的session
|
* @return 当前会话的session
|
||||||
@@ -463,6 +505,7 @@ public class StpLogic {
|
|||||||
|
|
||||||
// =================== token专属session ===================
|
// =================== token专属session ===================
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定token的专属session,如果session尚未创建,isCreate代表是否新建并返回
|
* 获取指定token的专属session,如果session尚未创建,isCreate代表是否新建并返回
|
||||||
* @param tokenValue token值
|
* @param tokenValue token值
|
||||||
@@ -473,6 +516,7 @@ public class StpLogic {
|
|||||||
return getSessionBySessionId(getKeyTokenSession(tokenValue), isCreate);
|
return getSessionBySessionId(getKeyTokenSession(tokenValue), isCreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定token的专属session,如果session尚未创建,则新建并返回
|
* 获取指定token的专属session,如果session尚未创建,则新建并返回
|
||||||
* @param tokenValue token值
|
* @param tokenValue token值
|
||||||
@@ -482,6 +526,7 @@ public class StpLogic {
|
|||||||
return getSessionBySessionId(getKeyTokenSession(tokenValue), true);
|
return getSessionBySessionId(getKeyTokenSession(tokenValue), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前token的专属-session,如果session尚未创建,isCreate代表是否新建并返回
|
* 获取当前token的专属-session,如果session尚未创建,isCreate代表是否新建并返回
|
||||||
* @param isCreate 是否新建
|
* @param isCreate 是否新建
|
||||||
@@ -502,6 +547,7 @@ public class StpLogic {
|
|||||||
return getSessionBySessionId(getKeyTokenSession(getTokenValue()), isCreate);
|
return getSessionBySessionId(getKeyTokenSession(getTokenValue()), isCreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前token的专属-session,如果session尚未创建,则新建并返回
|
* 获取当前token的专属-session,如果session尚未创建,则新建并返回
|
||||||
* @return session会话
|
* @return session会话
|
||||||
@@ -513,6 +559,7 @@ public class StpLogic {
|
|||||||
|
|
||||||
// =================== [临时过期] 验证相关 ===================
|
// =================== [临时过期] 验证相关 ===================
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写入指定token的 [最后操作时间] 为当前时间戳
|
* 写入指定token的 [最后操作时间] 为当前时间戳
|
||||||
* @param tokenValue 指定token
|
* @param tokenValue 指定token
|
||||||
@@ -526,6 +573,7 @@ public class StpLogic {
|
|||||||
SaTokenManager.getSaTokenDao().setValue(getKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()), getConfig().getTimeout());
|
SaTokenManager.getSaTokenDao().setValue(getKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()), getConfig().getTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清除指定token的 [最后操作时间]
|
* 清除指定token的 [最后操作时间]
|
||||||
* @param tokenValue 指定token
|
* @param tokenValue 指定token
|
||||||
@@ -541,6 +589,7 @@ public class StpLogic {
|
|||||||
SaTokenManager.getSaTokenServlet().getRequest().removeAttribute(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY);
|
SaTokenManager.getSaTokenServlet().getRequest().removeAttribute(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查指定token 是否已经[临时过期],如果已经过期则抛出异常
|
* 检查指定token 是否已经[临时过期],如果已经过期则抛出异常
|
||||||
* @param tokenValue 指定token
|
* @param tokenValue 指定token
|
||||||
@@ -572,6 +621,7 @@ public class StpLogic {
|
|||||||
request.setAttribute(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY, true);
|
request.setAttribute(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查当前token 是否已经[临时过期],如果已经过期则抛出异常
|
* 检查当前token 是否已经[临时过期],如果已经过期则抛出异常
|
||||||
*/
|
*/
|
||||||
@@ -579,6 +629,7 @@ public class StpLogic {
|
|||||||
checkActivityTimeout(getTokenValue());
|
checkActivityTimeout(getTokenValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 续签指定token:(将 [最后操作时间] 更新为当前时间戳)
|
* 续签指定token:(将 [最后操作时间] 更新为当前时间戳)
|
||||||
* @param tokenValue 指定token
|
* @param tokenValue 指定token
|
||||||
@@ -591,6 +642,7 @@ public class StpLogic {
|
|||||||
SaTokenManager.getSaTokenDao().updateValue(getKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()));
|
SaTokenManager.getSaTokenDao().updateValue(getKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 续签当前token:(将 [最后操作时间] 更新为当前时间戳)
|
* 续签当前token:(将 [最后操作时间] 更新为当前时间戳)
|
||||||
* <h1>请注意: 即时token已经 [临时过期] 也可续签成功,
|
* <h1>请注意: 即时token已经 [临时过期] 也可续签成功,
|
||||||
@@ -827,7 +879,6 @@ public class StpLogic {
|
|||||||
|
|
||||||
// =================== id 反查token 相关操作 ===================
|
// =================== id 反查token 相关操作 ===================
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定loginId的tokenValue
|
* 获取指定loginId的tokenValue
|
||||||
* <p> 在配置为允许并发登录时,此方法只会返回队列的最后一个token,
|
* <p> 在配置为允许并发登录时,此方法只会返回队列的最后一个token,
|
||||||
@@ -836,16 +887,38 @@ public class StpLogic {
|
|||||||
* @return token值
|
* @return token值
|
||||||
*/
|
*/
|
||||||
public String getTokenValueByLoginId(Object loginId) {
|
public String getTokenValueByLoginId(Object loginId) {
|
||||||
List<String> tokenValueList = getTokenValueListByLoginId(loginId);
|
return getTokenValueByLoginId(loginId, SaTokenConsts.DEFAULT_LOGIN_DEVICE);
|
||||||
return tokenValueList.size() == 0 ? null : tokenValueList.get(tokenValueList.size() - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定loginId的tokenValue
|
* 获取指定loginId的tokenValue
|
||||||
|
* <p> 在配置为允许并发登录时,此方法只会返回队列的最后一个token,
|
||||||
|
* 如果你需要返回此账号id的所有token,请调用 getTokenValueListByLoginId
|
||||||
|
* @param loginId 账号id
|
||||||
|
* @param device 设备标识
|
||||||
|
* @return token值
|
||||||
|
*/
|
||||||
|
public String getTokenValueByLoginId(Object loginId, String device) {
|
||||||
|
List<String> tokenValueList = getTokenValueListByLoginId(loginId, device);
|
||||||
|
return tokenValueList.size() == 0 ? null : tokenValueList.get(tokenValueList.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定loginId的tokenValue集合
|
||||||
* @param loginId 账号id
|
* @param loginId 账号id
|
||||||
* @return 此loginId的所有相关token
|
* @return 此loginId的所有相关token
|
||||||
*/
|
*/
|
||||||
public List<String> getTokenValueListByLoginId(Object loginId) {
|
public List<String> getTokenValueListByLoginId(Object loginId) {
|
||||||
|
return getTokenValueListByLoginId(loginId, SaTokenConsts.DEFAULT_LOGIN_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定loginId的tokenValue集合
|
||||||
|
* @param loginId 账号id
|
||||||
|
* @param device 设备标识
|
||||||
|
* @return 此loginId的所有相关token
|
||||||
|
*/
|
||||||
|
public List<String> getTokenValueListByLoginId(Object loginId, String device) {
|
||||||
// 如果session为null的话直接返回空集合
|
// 如果session为null的话直接返回空集合
|
||||||
SaSession session = getSessionByLoginId(loginId, false);
|
SaSession session = getSessionByLoginId(loginId, false);
|
||||||
if(session == null) {
|
if(session == null) {
|
||||||
@@ -855,11 +928,42 @@ public class StpLogic {
|
|||||||
List<TokenSign> tokenSignList = session.getTokenSignList();
|
List<TokenSign> tokenSignList = session.getTokenSignList();
|
||||||
List<String> tokenValueList = new ArrayList<>();
|
List<String> tokenValueList = new ArrayList<>();
|
||||||
for (TokenSign tokenSign : tokenSignList) {
|
for (TokenSign tokenSign : tokenSignList) {
|
||||||
|
if(tokenSign.getDevice().equals(device)) {
|
||||||
tokenValueList.add(tokenSign.getValue());
|
tokenValueList.add(tokenSign.getValue());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return tokenValueList;
|
return tokenValueList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回当前token的登录设备
|
||||||
|
* @return 当前令牌的登录设备
|
||||||
|
*/
|
||||||
|
public String getLoginDevice() {
|
||||||
|
// 如果没有token,直接返回
|
||||||
|
String tokenValue = getTokenValue();
|
||||||
|
if(tokenValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 如果还未登录,直接返回 null
|
||||||
|
if(isLogin() == false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 如果session为null的话直接返回 null
|
||||||
|
SaSession session = getSession(false);
|
||||||
|
if(session == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 遍历解析
|
||||||
|
List<TokenSign> tokenSignList = session.getTokenSignList();
|
||||||
|
for (TokenSign tokenSign : tokenSignList) {
|
||||||
|
if(tokenSign.getValue().equals(tokenValue)) {
|
||||||
|
return tokenSign.getDevice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// =================== 返回相应key ===================
|
// =================== 返回相应key ===================
|
||||||
|
|
||||||
@@ -870,6 +974,7 @@ public class StpLogic {
|
|||||||
public String getKeyTokenName() {
|
public String getKeyTokenName() {
|
||||||
return getConfig().getTokenName();
|
return getConfig().getTokenName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取key: tokenValue 持久化 token-id
|
* 获取key: tokenValue 持久化 token-id
|
||||||
* @param tokenValue token值
|
* @param tokenValue token值
|
||||||
@@ -878,6 +983,7 @@ public class StpLogic {
|
|||||||
public String getKeyTokenValue(String tokenValue) {
|
public String getKeyTokenValue(String tokenValue) {
|
||||||
return getConfig().getTokenName() + ":" + loginKey + ":token:" + tokenValue;
|
return getConfig().getTokenName() + ":" + loginKey + ":token:" + tokenValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取key: session 持久化
|
* 获取key: session 持久化
|
||||||
* @param loginId 账号id
|
* @param loginId 账号id
|
||||||
@@ -886,6 +992,7 @@ public class StpLogic {
|
|||||||
public String getKeySession(Object loginId) {
|
public String getKeySession(Object loginId) {
|
||||||
return getConfig().getTokenName() + ":" + loginKey + ":session:" + loginId;
|
return getConfig().getTokenName() + ":" + loginKey + ":session:" + loginId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取key: tokenValue的专属session
|
* 获取key: tokenValue的专属session
|
||||||
* @param tokenValue token值
|
* @param tokenValue token值
|
||||||
@@ -894,6 +1001,7 @@ public class StpLogic {
|
|||||||
public String getKeyTokenSession(String tokenValue) {
|
public String getKeyTokenSession(String tokenValue) {
|
||||||
return getConfig().getTokenName() + ":" + loginKey + ":token-session:" + tokenValue;
|
return getConfig().getTokenName() + ":" + loginKey + ":token-session:" + tokenValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取key: 指定token的最后操作时间 持久化
|
* 获取key: 指定token的最后操作时间 持久化
|
||||||
* @param tokenValue token值
|
* @param tokenValue token值
|
||||||
|
@@ -61,6 +61,15 @@ public class StpUtil {
|
|||||||
stpLogic.setLoginId(loginId);
|
stpLogic.setLoginId(loginId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在当前会话上登录id
|
||||||
|
* @param loginId 登录id,建议的类型:(long | int | String)
|
||||||
|
* @param device 设备标识
|
||||||
|
*/
|
||||||
|
public static void setLoginId(Object loginId, String device) {
|
||||||
|
stpLogic.setLoginId(loginId, device);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前会话注销登录
|
* 当前会话注销登录
|
||||||
*/
|
*/
|
||||||
@@ -85,6 +94,16 @@ public class StpUtil {
|
|||||||
stpLogic.logoutByLoginId(loginId);
|
stpLogic.logoutByLoginId(loginId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定loginId指定设备的会话注销登录(踢人下线)
|
||||||
|
* <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-2
|
||||||
|
* @param loginId 账号id
|
||||||
|
* @param device 设备标识
|
||||||
|
*/
|
||||||
|
public static void logoutByLoginId(Object loginId, String device) {
|
||||||
|
stpLogic.logoutByLoginId(loginId, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 查询相关
|
// 查询相关
|
||||||
|
|
||||||
@@ -384,6 +403,18 @@ public class StpUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定loginId的tokenValue
|
* 获取指定loginId的tokenValue
|
||||||
|
* <p> 在配置为允许并发登录时,此方法只会返回队列的最后一个token,
|
||||||
|
* 如果你需要返回此账号id的所有token,请调用 getTokenValueListByLoginId
|
||||||
|
* @param loginId 账号id
|
||||||
|
* @param device 设备标识
|
||||||
|
* @return token值
|
||||||
|
*/
|
||||||
|
public static String getTokenValueByLoginId(Object loginId, String device) {
|
||||||
|
return stpLogic.getTokenValueByLoginId(loginId, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定loginId的tokenValue集合
|
||||||
* @param loginId 账号id
|
* @param loginId 账号id
|
||||||
* @return 此loginId的所有相关token
|
* @return 此loginId的所有相关token
|
||||||
*/
|
*/
|
||||||
@@ -391,5 +422,22 @@ public class StpUtil {
|
|||||||
return stpLogic.getTokenValueListByLoginId(loginId);
|
return stpLogic.getTokenValueListByLoginId(loginId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定loginId的tokenValue集合
|
||||||
|
* @param loginId 账号id
|
||||||
|
* @param device 设备标识
|
||||||
|
* @return 此loginId的所有相关token
|
||||||
|
*/
|
||||||
|
public static List<String> getTokenValueListByLoginId(Object loginId, String device) {
|
||||||
|
return stpLogic.getTokenValueListByLoginId(loginId, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回当前token的登录设备
|
||||||
|
* @return 当前令牌的登录设备
|
||||||
|
*/
|
||||||
|
public static String getLoginDevice() {
|
||||||
|
return stpLogic.getLoginDevice();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -39,7 +39,8 @@ public class TestController {
|
|||||||
System.out.println("登录成功");
|
System.out.println("登录成功");
|
||||||
System.out.println("当前是否登录:" + StpUtil.isLogin());
|
System.out.println("当前是否登录:" + StpUtil.isLogin());
|
||||||
System.out.println("当前登录账号:" + StpUtil.getLoginId());
|
System.out.println("当前登录账号:" + StpUtil.getLoginId());
|
||||||
System.out.println("当前登录账号:" + StpUtil.getLoginIdAsInt()); // 获取登录id并转为int
|
// System.out.println("当前登录账号并转为int:" + StpUtil.getLoginIdAsInt());
|
||||||
|
System.out.println("当前登录设备:" + StpUtil.getLoginDevice());
|
||||||
// System.out.println("当前token信息:" + StpUtil.getTokenInfo());
|
// System.out.println("当前token信息:" + StpUtil.getTokenInfo());
|
||||||
|
|
||||||
return AjaxJson.getSuccess();
|
return AjaxJson.getSuccess();
|
||||||
@@ -194,10 +195,18 @@ public class TestController {
|
|||||||
// 测试 浏览器访问: http://localhost:8081/test/test
|
// 测试 浏览器访问: http://localhost:8081/test/test
|
||||||
@RequestMapping("test")
|
@RequestMapping("test")
|
||||||
public AjaxJson test() {
|
public AjaxJson test() {
|
||||||
StpUtil.getTokenSession().logout();
|
// StpUtil.getTokenSession().logout();
|
||||||
|
StpUtil.logoutByLoginId(10001);
|
||||||
return AjaxJson.getSuccess();
|
return AjaxJson.getSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 测试登录接口, 按照设备登录, 浏览器访问: http://localhost:8081/test/login2
|
||||||
|
@RequestMapping("login2")
|
||||||
|
public AjaxJson login2(@RequestParam(defaultValue="10001") String id, @RequestParam(defaultValue="PC") String device) {
|
||||||
|
StpUtil.setLoginId(id, device);
|
||||||
|
return AjaxJson.getSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user