v1.9.0 新特性 同端互斥登录

This commit is contained in:
shengzhang
2021-01-05 13:58:51 +08:00
parent 4ff6a87ef5
commit 9733c8777a
4 changed files with 228 additions and 68 deletions

View File

@@ -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 {
} }

View File

@@ -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值

View File

@@ -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();
}
} }

View File

@@ -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();
}
} }