diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenEventCenter.java b/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenEventCenter.java index 0caca54e..68228dba 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenEventCenter.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenEventCenter.java @@ -22,7 +22,7 @@ import cn.dev33.satoken.annotation.handler.SaAnnotationHandlerInterface; import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.error.SaErrorCode; import cn.dev33.satoken.exception.SaTokenException; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.StpLogic; /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListener.java b/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListener.java index 289b7d46..ed0ca42a 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListener.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListener.java @@ -17,7 +17,7 @@ package cn.dev33.satoken.listener; import cn.dev33.satoken.annotation.handler.SaAnnotationHandlerInterface; import cn.dev33.satoken.config.SaTokenConfig; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.StpLogic; /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListenerForLog.java b/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListenerForLog.java index 76c888d8..cb770e83 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListenerForLog.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListenerForLog.java @@ -17,7 +17,7 @@ package cn.dev33.satoken.listener; import cn.dev33.satoken.annotation.handler.SaAnnotationHandlerInterface; import cn.dev33.satoken.config.SaTokenConfig; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.util.SaFoxUtil; diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListenerForSimple.java b/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListenerForSimple.java index 0bce1d3f..f7e30f5c 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListenerForSimple.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/listener/SaTokenListenerForSimple.java @@ -15,7 +15,7 @@ */ package cn.dev33.satoken.listener; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; /** * Sa-Token 侦听器,默认空实现 diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/session/SaSession.java b/sa-token-core/src/main/java/cn/dev33/satoken/session/SaSession.java index f6851c14..a7eb002d 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/session/SaSession.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/session/SaSession.java @@ -88,6 +88,11 @@ public class SaSession implements SaSetValueInterface, Serializable { */ private String token; + /** + * 当前账号历史总计登录设备数量 (当此 SaSession 属于 Account-Session 时,此值有效) + */ + private int historyTerminalCount; + /** * 此 SaSession 的创建时间(13位时间戳) */ @@ -330,6 +335,8 @@ public class SaSession implements SaSetValueInterface, Serializable { terminalList.remove(oldTerminal); } // 然后添加新的 + this.historyTerminalCount++; + terminalInfo.setIndex(this.historyTerminalCount); terminalList.add(terminalInfo); update(); } @@ -347,20 +354,24 @@ public class SaSession implements SaSetValueInterface, Serializable { } /** - * 获取最大的终端索引值,如无返0 + * 获取 当前账号历史总计登录设备数量 (当此 SaSession 属于 Account-Session 时,此值有效) + * * @return / */ - public int maxTerminalIndex() { - int max = 0; - for (SaTerminalInfo terminal : terminalListCopy()) { - int index = terminal.getIndex(); - if (index > max) { - max = index; - } - } - return max; + public int getHistoryTerminalCount() { + return this.historyTerminalCount; } + /** + * 设置 当前账号历史总计登录设备数量 (当此 SaSession 属于 Account-Session 时,此值有效) + * + * @param historyTerminalCount / + */ + public void setHistoryTerminalCount(int historyTerminalCount) { + this.historyTerminalCount = historyTerminalCount; + } + + /** * 判断指定设备 id 是否为可信任设备 * @param deviceId / diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginConfig.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginConfig.java index 49f5d830..4997f053 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginConfig.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginConfig.java @@ -16,6 +16,7 @@ package cn.dev33.satoken.stp; import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import java.util.Map; diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java index d54a104d..b62132dd 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginModel.java @@ -15,6 +15,8 @@ */ package cn.dev33.satoken.stp; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; + /** *
当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
+ * + * @param tokenValue 指定 token + */ + public void kickoutByTokenValue(String tokenValue) { + kickoutByTokenValue(tokenValue, createSaLogoutParameter()); + } + + /** + * 踢人下线,根据指定 token、注销参数 + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
+ * + * @param tokenValue 指定 token + * @param logoutParameter 注销参数 + */ + public void kickoutByTokenValue(String tokenValue, SaLogoutParameter logoutParameter) { + _logoutByTokenValue(tokenValue, logoutParameter.setMode(SaLogoutMode.KICKOUT)); + } + + /** + * 顶人下线,根据指定 token + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4
+ * + * @param tokenValue 指定 token + */ + public void replacedByTokenValue(String tokenValue) { + replacedByTokenValue(tokenValue, createSaLogoutParameter()); + } + + /** + * 顶人下线,根据指定 token、注销参数 + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4
+ * + * @param tokenValue 指定 token + * @param logoutParameter / + */ + public void replacedByTokenValue(String tokenValue, SaLogoutParameter logoutParameter) { + _logoutByTokenValue(tokenValue, logoutParameter.setMode(SaLogoutMode.REPLACED)); + } + + /** + * [work] 注销下线,根据指定 token 、注销参数 + * + * @param tokenValue 指定 token + * @param logoutParameter 注销参数 + */ + public void _logoutByTokenValue(String tokenValue, SaLogoutParameter logoutParameter) { + + // 1、判断一下:如果此 token 映射的是一个无效 loginId,则此处立即返回,不需要再往下处理了 + // 如果不提前截止,则后续的操作可能会写入意外数据 + Object loginId = getLoginIdByTokenNotThinkFreeze(tokenValue); + if( SaFoxUtil.isEmpty(loginId) ) { + return; + } + if(!logoutParameter.getIsKeepFreezeOps() && isFreeze(tokenValue)) { + return; + } + + // 2、清除这个 token 的最后活跃时间记录 + if(isOpenCheckActiveTimeout()) { + clearLastActive(tokenValue); + } + + // 3、清除 Token-Session + if( ! logoutParameter.getIsKeepTokenSession()) { + deleteTokenSession(tokenValue); + } + + // 4、清理或更改 Token 映射 + // 5、发布事件通知 + // SaLogoutMode.LOGOUT:注销下线 + if(logoutParameter.getMode() == SaLogoutMode.LOGOUT) { + deleteTokenToIdMapping(tokenValue); + SaTokenEventCenter.doLogout(loginType, loginId, tokenValue); + } + // SaLogoutMode.LOGOUT:踢人下线 + if(logoutParameter.getMode() == SaLogoutMode.KICKOUT) { + updateTokenToIdMapping(tokenValue, NotLoginException.KICK_OUT); + SaTokenEventCenter.doKickout(loginType, loginId, tokenValue); + } + // SaLogoutMode.REPLACED:顶人下线 + if(logoutParameter.getMode() == SaLogoutMode.REPLACED) { + updateTokenToIdMapping(tokenValue, NotLoginException.BE_REPLACED); + SaTokenEventCenter.doReplaced(loginType, loginId, tokenValue); + } + + // 6、清理这个账号的 Account-Session 上的 terminal 信息,并且尝试注销掉 Account-Session + SaSession session = getSessionByLoginId(loginId, false); + if(session != null) { + session.removeTerminal(tokenValue); + session.logoutByTerminalCountToZero(); + } + } + + // --- 注销 (根据 loginId) + + /** + * 会话注销,根据账号id + * + * @param loginId 账号id */ public void logout(Object loginId) { - logout(loginId, null); + logout(loginId, createSaLogoutParameter()); } /** * 会话注销,根据账号id 和 设备类型 - * - * @param loginId 账号id + * + * @param loginId 账号id * @param deviceType 设备类型 (填 null 代表注销该账号的所有设备类型) */ public void logout(Object loginId, String deviceType) { + logout(loginId, createSaLogoutParameter().setDeviceType(deviceType)); + } + + /** + * 会话注销,根据账号id 和 注销参数 + * + * @param loginId 账号id + * @param logoutParameter 注销参数 + */ + public void logout(Object loginId, SaLogoutParameter logoutParameter) { + _logout(loginId, logoutParameter.setMode(SaLogoutMode.LOGOUT)); + } + + /** + * 踢人下线,根据账号id + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
+ * + * @param loginId 账号id + */ + public void kickout(Object loginId) { + kickout(loginId, createSaLogoutParameter()); + } + + /** + * 踢人下线,根据账号id 和 设备类型 + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
+ * + * @param loginId 账号id + * @param deviceType 设备类型 (填 null 代表踢出该账号的所有设备类型) + */ + public void kickout(Object loginId, String deviceType) { + kickout(loginId, createSaLogoutParameter().setDeviceType(deviceType)); + } + + /** + * 踢人下线,根据账号id 和 注销参数 + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
+ * + * @param loginId 账号id + * @param logoutParameter 注销参数 + */ + public void kickout(Object loginId, SaLogoutParameter logoutParameter) { + _logout(loginId, logoutParameter.setMode(SaLogoutMode.KICKOUT)); + } + + /** + * 顶人下线,根据账号id + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4
+ * + * @param loginId 账号id + */ + public void replaced(Object loginId) { + replaced(loginId, createSaLogoutParameter()); + } + + /** + * 顶人下线,根据账号id 和 设备类型 + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4
+ * + * @param loginId 账号id + * @param deviceType 设备类型 (填 null 代表顶替该账号的所有设备类型) + */ + public void replaced(Object loginId, String deviceType) { + replaced(loginId, createSaLogoutParameter().setDeviceType(deviceType)); + } + + /** + * 顶人下线,根据账号id 和 注销参数 + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4
+ * + * @param loginId 账号id + * @param logoutParameter 注销参数 + */ + public void replaced(Object loginId, SaLogoutParameter logoutParameter) { + _logout(loginId, logoutParameter.setMode(SaLogoutMode.REPLACED)); + } + + /** + * [work] 会话注销,根据账号id 和 注销参数 + * + * @param loginId 账号id + * @param logoutParameter 注销参数 + */ + public void _logout(Object loginId, SaLogoutParameter logoutParameter) { // 1、获取此账号的 Account-Session,上面记录了此账号的所有登录客户端数据 SaSession session = getSessionByLoginId(loginId, false); if(session != null) { - // 2、遍历此账号所有从这个 deviceType 设备类型上登录的客户端,清除相关数据 - for (SaTerminalInfo terminal: session.getTerminalListByDeviceType(deviceType)) { - - // 2.1、获取此客户端的 token 值 - String tokenValue = terminal.getTokenValue(); - - // 2.2、从 Account-Session 上清除此设备信息 - session.removeTerminal(tokenValue); - - // 2.3、清除这个 token 的最后活跃时间记录 - if(isOpenCheckActiveTimeout()) { - clearLastActive(tokenValue); - } - - // 2.4、清除 token -> id 的映射关系 - deleteTokenToIdMapping(tokenValue); - - // 2.5、清除这个 token 的 Token-Session 对象 - deleteTokenSession(tokenValue); - - // 2.6、$$ 发布事件:xx 账号的 xx 客户端注销了 - SaTokenEventCenter.doLogout(loginType, loginId, tokenValue); + // 2、遍历此 SaTerminalInfo 客户端列表,清除相关数据 + List当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
- * - * @param loginId 账号id - */ - public void kickout(Object loginId) { - kickout(loginId, null); - } - - /** - * 踢人下线,根据账号id 和 设备类型 - *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
- * - * @param loginId 账号id - * @param deviceType 设备类型 (填 null 代表踢出该账号的所有设备类型) - */ - public void kickout(Object loginId, String deviceType) { - // 1、获取此账号的 Account-Session,上面记录了此账号的所有登录客户端数据 - SaSession session = getSessionByLoginId(loginId, false); - if(session != null) { - - // 2、遍历此账号所有从这个 deviceType 设备上登录的客户端,清除相关数据 - for (SaTerminalInfo terminal: session.getTerminalListByDeviceType(deviceType)) { - - // 2.1、获取此客户端的 token 值 - String tokenValue = terminal.getTokenValue(); - - // 2.2、从 Account-Session 上清除 terminal 信息 - session.removeTerminal(tokenValue); - - // 2.3、清除这个 token 的最后活跃时间记录 - if(isOpenCheckActiveTimeout()) { - clearLastActive(tokenValue); - } - - // 2.4、将此 token 标记为:已被踢下线 - updateTokenToIdMapping(tokenValue, NotLoginException.KICK_OUT); - - // 2.5、清除 Token-Session - deleteTokenSession(tokenValue); - - // 2.6、$$ 发布事件:xx 账号的 xx 客户端被踢下线了 - SaTokenEventCenter.doKickout(loginType, loginId, tokenValue); - } - - // 3、如果代码走到这里的时候,此账号已经没有客户端在登录了,则直接注销掉这个 Account-Session - session.logoutByTerminalCountToZero(); - } - } - - /** - * 踢人下线,根据指定 token - *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
- * - * @param tokenValue 指定 token - */ - public void kickoutByTokenValue(String tokenValue) { - // 1、清除这个 token 的最后活跃时间记录 - if(isOpenCheckActiveTimeout()) { - clearLastActive(tokenValue); - } - - // 2、清除 Token-Session - deleteTokenSession(tokenValue); - - // 3、判断一下:如果此 token 映射的是一个无效 loginId,则此处立即返回,不需要再往下处理了 - String loginId = getLoginIdNotHandle(tokenValue); - if( ! isValidLoginId(loginId) ) { - return; - } - - // 4、将此 token 标记为:已被踢下线 - updateTokenToIdMapping(tokenValue, NotLoginException.KICK_OUT); - - // 5、$$. 发布事件:某某 token 被踢下线了 - SaTokenEventCenter.doKickout(loginType, loginId, tokenValue); - - // 6、清理这个账号的 Account-Session 上的 terminal 信息,并且尝试注销掉 Account-Session - SaSession session = getSessionByLoginId(loginId, false); - if(session != null) { - session.removeTerminal(tokenValue); - session.logoutByTerminalCountToZero(); - } - } - - /** - * 顶人下线,根据账号id 和 设备类型 - *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4
- * - * @param loginId 账号id - * @param deviceType 设备类型 (填 null 代表顶替该账号的所有设备类型) - */ - public void replaced(Object loginId, String deviceType) { - // 1、获取此账号的 Account-Session,上面记录了此账号的所有登录客户端数据 - SaSession session = getSessionByLoginId(loginId, false); - if(session != null) { - - // 2、遍历此账号所有从这个 deviceType 设备上登录的客户端,清除相关数据 - for (SaTerminalInfo ter: session.getTerminalListByDeviceType(deviceType)) { - - // 2.1、获取此客户端的 token 值 - String tokenValue = ter.getTokenValue(); - - // 2.2、从 Account-Session 上清除 terminal 信息 - session.removeTerminal(tokenValue); - - // 2.3、清除这个 token 的最后活跃时间记录 - if(isOpenCheckActiveTimeout()) { - clearLastActive(tokenValue); - } - - // 2.4、将此 token 标记为:已被顶下线 - updateTokenToIdMapping(tokenValue, NotLoginException.BE_REPLACED); - - // 2.5、清除 Token-Session 对象 - deleteTokenSession(tokenValue); - - // 2.6、$$ 发布事件:xx 账号的 xx 客户端注销了 - SaTokenEventCenter.doReplaced(loginType, loginId, tokenValue); - } - - // 3、因为调用顶替下线时,一般都是在新客户端正在登录,所以此处不需要清除该账号的 Account-Session - // 如果此处清除了 Account-Session,将可能导致 Account-Session 被注销后又立刻创建出来,造成不必要的性能浪费 - // session.logoutByTerminalCountToZero(); - } - } - // ---- 会话查询 /** @@ -1092,28 +1196,49 @@ public class StpLogic { } /** - * 获取指定 token 对应的账号id,如果未登录,则返回 null + * 获取指定 token 对应的账号id,如果 token 无效或 token 处于被踢、被顶、被冻结等状态,则返回 null * * @param tokenValue token * @return 账号id */ public Object getLoginIdByToken(String tokenValue) { - // 1、如果提供的 token 为空,则直接返回 null - if(SaFoxUtil.isEmpty(tokenValue)) { - return null; - } + Object loginId = getLoginIdByTokenNotThinkFreeze(tokenValue); - // 2、查找此 token 对应的 loginId,如果找不到或找的到但属于无效值,则返回 null - String loginId = getLoginIdNotHandle(tokenValue); - if( ! isValidLoginId(loginId) ) { - return null; - } + if( SaFoxUtil.isNotEmpty(loginId) ) { + // 如果 token 已被冻结,也返回 null + long activeTimeout = getTokenActiveTimeoutByToken(tokenValue); + if(activeTimeout == SaTokenDao.NOT_VALUE_EXPIRE) { + return null; + } + } - // 3、返回 return loginId; } + /** + * 获取指定 token 对应的账号id,如果 token 无效或 token 处于被踢、被顶等状态 (不考虑被冻结),则返回 null + * + * @param tokenValue token + * @return 账号id + */ + public Object getLoginIdByTokenNotThinkFreeze(String tokenValue) { + + // 1、如果提供的 token 为空,则直接返回 null + if(SaFoxUtil.isEmpty(tokenValue)) { + return null; + } + + // 2、查找此 token 对应的 loginId,如果找不到或找的到但属于无效值,则返回 null + String loginId = getLoginIdNotHandle(tokenValue); + if( ! isValidLoginId(loginId) ) { + return null; + } + + // 3、返回 + return loginId; + } + /** * 获取指定 token 对应的账号id (不做任何特殊处理) * @@ -1530,24 +1655,36 @@ public class StpLogic { protected void clearLastActive(String tokenValue) { getSaTokenDao().delete(splicingKeyLastActiveTime(tokenValue)); } - - /** + + /** + * 判断指定 token 是否已被冻结 + * + * @param tokenValue 指定 token + */ + public boolean isFreeze(String tokenValue) { + + // 1、获取这个 token 的剩余活跃有效期 + long activeTimeout = getTokenActiveTimeoutByToken(tokenValue); + + // 2、值为 -1 代表此 token 已经被设置永不冻结 + if(activeTimeout == SaTokenDao.NEVER_EXPIRE) { + return false; + } + + // 3、值为 -2 代表已被冻结 + if(activeTimeout == SaTokenDao.NOT_VALUE_EXPIRE) { + return true; + } + return false; + } + + /** * 检查指定 token 是否已被冻结,如果是则抛出异常 * * @param tokenValue 指定 token */ public void checkActiveTimeout(String tokenValue) { - - // 1、获取这个 token 的剩余活跃有效期 - long activeTimeout = getTokenActiveTimeoutByToken(tokenValue); - - // 2、值为 -1 代表此 token 已经被设置永不冻结,无须继续验证 - if(activeTimeout == SaTokenDao.NEVER_EXPIRE) { - return; - } - - // 3、值为 -2 代表已被冻结,此时需要抛出异常 - if(activeTimeout == SaTokenDao.NOT_VALUE_EXPIRE) { + if (isFreeze(tokenValue)) { throw NotLoginException.newInstance(loginType, TOKEN_FREEZE, TOKEN_FREEZE_MESSAGE, tokenValue).setCode(SaErrorCode.CODE_11016); } } @@ -2929,6 +3066,15 @@ public class StpLogic { return new SaLoginParameter(getConfigOrGlobal()); } + /** + * 根据当前配置对象创建一个 SaLogoutParameter 对象 + * + * @return / + */ + public SaLogoutParameter createSaLogoutParameter() { + return new SaLogoutParameter(getConfigOrGlobal()); + } + // ------------------- 过期方法 ------------------- diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java index 42d81650..a879f1d4 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java @@ -20,6 +20,8 @@ import cn.dev33.satoken.fun.SaFunction; import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaTerminalInfo; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLogoutParameter; import java.util.List; @@ -235,7 +237,7 @@ public class StpUtil { return stpLogic.getOrCreateLoginSession(id); } - // --- 注销 + // --- 注销 (根据 token) /** * 在当前客户端会话注销 @@ -245,7 +247,77 @@ public class StpUtil { } /** - * 会话注销,根据账号id + * 在当前客户端会话注销,根据注销参数 + */ + public static void logout(SaLogoutParameter logoutParameter) { + stpLogic.logout(logoutParameter); + } + + /** + * 注销下线,根据指定 token + * + * @param tokenValue 指定 token + */ + public static void logoutByTokenValue(String tokenValue) { + stpLogic.logoutByTokenValue(tokenValue); + } + + /** + * 注销下线,根据指定 token、注销参数 + * + * @param tokenValue 指定 token + * @param logoutParameter / + */ + public static void logoutByTokenValue(String tokenValue, SaLogoutParameter logoutParameter) { + stpLogic.logoutByTokenValue(tokenValue, logoutParameter); + } + + /** + * 踢人下线,根据指定 token + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
+ * + * @param tokenValue 指定 token + */ + public static void kickoutByTokenValue(String tokenValue) { + stpLogic.kickoutByTokenValue(tokenValue); + } + + /** + * 踢人下线,根据指定 token、注销参数 + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
+ * + * @param tokenValue 指定 token + * @param logoutParameter 注销参数 + */ + public static void kickoutByTokenValue(String tokenValue, SaLogoutParameter logoutParameter) { + stpLogic.kickoutByTokenValue(tokenValue, logoutParameter); + } + + /** + * 顶人下线,根据指定 token + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4
+ * + * @param tokenValue 指定 token + */ + public static void replacedByTokenValue(String tokenValue) { + stpLogic.replacedByTokenValue(tokenValue); + } + + /** + * 顶人下线,根据指定 token、注销参数 + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4
+ * + * @param tokenValue 指定 token + * @param logoutParameter / + */ + public static void replacedByTokenValue(String tokenValue, SaLogoutParameter logoutParameter) { + stpLogic.replacedByTokenValue(tokenValue, logoutParameter); + } + + // --- 注销 (根据 loginId) + + /** + * 会话注销,根据账号id * * @param loginId 账号id */ @@ -256,7 +328,7 @@ public class StpUtil { /** * 会话注销,根据账号id 和 设备类型 * - * @param loginId 账号id + * @param loginId 账号id * @param deviceType 设备类型 (填 null 代表注销该账号的所有设备类型) */ public static void logout(Object loginId, String deviceType) { @@ -264,19 +336,20 @@ public class StpUtil { } /** - * 会话注销,根据指定 Token + * 会话注销,根据账号id 和 注销参数 * - * @param tokenValue 指定 token + * @param loginId 账号id + * @param logoutParameter 注销参数 */ - public static void logoutByTokenValue(String tokenValue) { - stpLogic.logoutByTokenValue(tokenValue); + public static void logout(Object loginId, SaLogoutParameter logoutParameter) { + stpLogic.logout(loginId, logoutParameter); } /** - * 踢人下线,根据账号id + * 踢人下线,根据账号id *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
* - * @param loginId 账号id + * @param loginId 账号id */ public static void kickout(Object loginId) { stpLogic.kickout(loginId); @@ -294,13 +367,24 @@ public class StpUtil { } /** - * 踢人下线,根据指定 token + * 踢人下线,根据账号id 和 注销参数 *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-5
* - * @param tokenValue 指定 token + * @param loginId 账号id + * @param logoutParameter 注销参数 */ - public static void kickoutByTokenValue(String tokenValue) { - stpLogic.kickoutByTokenValue(tokenValue); + public static void kickout(Object loginId, SaLogoutParameter logoutParameter) { + stpLogic.kickout(loginId, logoutParameter); + } + + /** + * 顶人下线,根据账号id + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4
+ * + * @param loginId 账号id + */ + public static void replaced(Object loginId) { + stpLogic.replaced(loginId); } /** @@ -314,6 +398,47 @@ public class StpUtil { stpLogic.replaced(loginId, deviceType); } + /** + * 顶人下线,根据账号id 和 注销参数 + *当对方再次访问系统时,会抛出 NotLoginException 异常,场景值=-4
+ * + * @param loginId 账号id + * @param logoutParameter 注销参数 + */ + public static void replaced(Object loginId, SaLogoutParameter logoutParameter) { + stpLogic.replaced(loginId, logoutParameter); + } + + // --- 注销 (会话管理辅助方法) + + /** + * 在 Account-Session 上移除 Terminal 信息 (注销下线方式) + * @param session / + * @param terminal / + */ + public static void removeTerminalByLogout(SaSession session, SaTerminalInfo terminal) { + stpLogic.removeTerminalByLogout(session, terminal); + } + + /** + * 在 Account-Session 上移除 Terminal 信息 (踢人下线方式) + * @param session / + * @param terminal / + */ + public static void removeTerminalByKickout(SaSession session, SaTerminalInfo terminal) { + stpLogic.removeTerminalByKickout(session, terminal); + } + + /** + * 在 Account-Session 上移除 Terminal 信息 (顶人下线方式) + * @param session / + * @param terminal / + */ + public static void removeTerminalByReplaced(SaSession session, SaTerminalInfo terminal) { + stpLogic.removeTerminalByReplaced(session, terminal); + } + + // 会话查询 /** @@ -398,7 +523,7 @@ public class StpUtil { } /** - * 获取指定 token 对应的账号id,如果未登录,则返回 null + * 获取指定 token 对应的账号id,如果 token 无效或 token 处于被踢、被顶、被冻结等状态,则返回 null * * @param tokenValue token * @return 账号id @@ -407,6 +532,16 @@ public class StpUtil { return stpLogic.getLoginIdByToken(tokenValue); } + /** + * 获取指定 token 对应的账号id,如果 token 无效或 token 处于被踢、被顶等状态 (不考虑被冻结),则返回 null + * + * @param tokenValue token + * @return 账号id + */ + public Object getLoginIdByTokenNotThinkFreeze(String tokenValue) { + return stpLogic.getLoginIdByTokenNotThinkFreeze(tokenValue); + } + /** * 获取当前 Token 的扩展信息(此函数只在jwt模式下生效) * diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginParameter.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLoginParameter.java similarity index 88% rename from sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginParameter.java rename to sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLoginParameter.java index d79162f8..c4e4870b 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/SaLoginParameter.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLoginParameter.java @@ -13,18 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package cn.dev33.satoken.stp; +package cn.dev33.satoken.stp.parameter; import cn.dev33.satoken.SaManager; import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.dao.SaTokenDao; +import cn.dev33.satoken.stp.parameter.enums.SaLogoutMode; +import cn.dev33.satoken.stp.parameter.enums.SaReplacedMode; import cn.dev33.satoken.util.SaTokenConsts; import java.util.LinkedHashMap; import java.util.Map; /** - * 在调用 `StpUtil.login()` 时的 配置参数 Model,决定登录的一些细节行为* // 例如:在登录时指定 token 有效期为七天,代码如下: @@ -48,6 +50,16 @@ public class SaLoginParameter { */ private String deviceId; + /** + * 顶人下线的范围 + */ + private SaReplacedMode replacedMode = SaReplacedMode.CURR_DEVICE_TYPE; + + /** + * 溢出 maxLoginCount 的客户端,将以何种方式注销下线 + */ + private SaLogoutMode overflowLogoutMode = SaLogoutMode.LOGOUT; + /** * 扩展信息(只在 jwt 模式下生效) */ @@ -123,7 +135,7 @@ public class SaLoginParameter { * @return 对象自身 */ public SaLoginParameter setDefaultValues(SaTokenConfig config) { - this.deviceType = SaTokenConsts.DEFAULT_LOGIN_DEVICE; + this.deviceType = SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE; this.timeout = config.getTimeout(); this.isConcurrent = config.getIsConcurrent(); this.isShare = config.getIsShare(); @@ -220,9 +232,9 @@ public class SaLoginParameter { /** * @return 获取device参数,如果为null,则返回默认值 */ - public String getDeviceOrDefault() { + public String getDeviceTypeOrDefault() { if(deviceType == null) { - return SaTokenConsts.DEFAULT_LOGIN_DEVICE; + return SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE; } return deviceType; } @@ -274,6 +286,45 @@ public class SaLoginParameter { return this; } + /** + * 获取 顶人下线的范围 + * + * @return replacedMode 顶人下线的范围 + */ + public SaReplacedMode getReplacedMode() { + return this.replacedMode; + } + + /** + * 设置 顶人下线的范围 + * + * @param replacedMode / + * @return 对象自身 + */ + public SaLoginParameter setReplacedMode(SaReplacedMode replacedMode) { + this.replacedMode = replacedMode; + return this; + } + + /** + * 获取 溢出 maxLoginCount 的客户端,将以何种方式注销下线 + * + * @return overflowLogoutMode / + */ + public SaLogoutMode getOverflowLogoutMode() { + return this.overflowLogoutMode; + } + + /** + * 设置 溢出 maxLoginCount 的客户端,将以何种方式注销下线 + * + * @param overflowLogoutMode / + * @return 对象自身 + */ + public SaLoginParameter setOverflowLogoutMode(SaLogoutMode overflowLogoutMode) { + this.overflowLogoutMode = overflowLogoutMode; + return this; + } /** * @return 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在) */ @@ -462,6 +513,8 @@ public class SaLoginParameter { return "SaLoginParameter [" + "deviceType=" + deviceType + ", deviceId=" + deviceId + + ", replacedMode=" + replacedMode + + ", overflowLogoutMode=" + overflowLogoutMode + ", isLastingCookie=" + isLastingCookie + ", timeout=" + timeout + ", activeTimeout=" + activeTimeout diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLogoutParameter.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLogoutParameter.java new file mode 100644 index 00000000..cd03bcf1 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/SaLogoutParameter.java @@ -0,0 +1,203 @@ +/* + * 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.stp.parameter; + +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.config.SaTokenConfig; +import cn.dev33.satoken.stp.parameter.enums.SaLogoutMode; +import cn.dev33.satoken.stp.parameter.enums.SaLogoutRange; + +/** + * 在会话注销时的 配置参数对象,决定注销时的一些细节行为
+ * + *+ * // 例如: + * StpUtil.logout(10001, new SaLogoutParameter()); + *+ * + * @author click33 + * @since 1.41.0 + */ +public class SaLogoutParameter { + + /** + * 是否保留 Token-Session + */ + private Boolean isKeepTokenSession = false; + + /** + * 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API) + */ + private Boolean isKeepFreezeOps = false; + + /** + * 设备类型 (如果不指定,则默认注销所有客户端) + */ + private String deviceType; + + /** + * 注销类型 + */ + private SaLogoutMode mode = SaLogoutMode.LOGOUT; + + /** + * 注销范围 (此参数只在调用 StpUtil.logout(new SaLogoutParameter()) 时有效) + */ + private SaLogoutRange range = SaLogoutRange.TOKEN; + + + // ------ 附加方法 + + public SaLogoutParameter() { + this(SaManager.getConfig()); + } + public SaLogoutParameter(SaTokenConfig config) { + setDefaultValues(config); + } + + /** + * 根据 SaTokenConfig 对象初始化默认值 + * + * @param config 使用的配置对象 + * @return 对象自身 + */ + public SaLogoutParameter setDefaultValues(SaTokenConfig config) { + return this; + } + + /** + * 静态方法获取一个 SaLoginParameter 对象 + * @return SaLoginParameter 对象 + */ + public static SaLogoutParameter create() { + return new SaLogoutParameter(SaManager.getConfig()); + } + + + + // ---------------- get set + + /** + * @return 是否保留 Token-Session + */ + public Boolean getIsKeepTokenSession() { + return isKeepTokenSession; + } + + /** + * @param isKeepTokenSession 是否保留 Token-Session + * + * @return 对象自身 + */ + public SaLogoutParameter setIsKeepTokenSession(Boolean isKeepTokenSession) { + this.isKeepTokenSession = isKeepTokenSession; + return this; + } + + /** + * 获取 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API) + * + * @return / + */ + public Boolean getIsKeepFreezeOps() { + return this.isKeepFreezeOps; + } + + /** + * 设置 如果 token 已被冻结,是否保留其操作权 (是否允许此 token 调用注销API) + * + * @param isKeepFreezeOps / + * @return 对象自身 + */ + public SaLogoutParameter setIsKeepFreezeOps(Boolean isKeepFreezeOps) { + this.isKeepFreezeOps = isKeepFreezeOps; + return this; + } + /** + * 获取 设备类型 (如果不指定,则默认注销所有客户端) + * + * @return deviceType / + */ + public String getDeviceType() { + return this.deviceType; + } + + /** + * 设置 设备类型 (如果不指定,则默认注销所有客户端) + * + * @param deviceType / + * @return / + */ + public SaLogoutParameter setDeviceType(String deviceType) { + this.deviceType = deviceType; + return this; + } + + /** + * 获取 注销类型 + * + * @return logoutMode 注销类型 + */ + public SaLogoutMode getMode() { + return this.mode; + } + + /** + * 设置 注销类型 + * + * @param mode 注销类型 + * @return / + */ + public SaLogoutParameter setMode(SaLogoutMode mode) { + this.mode = mode; + return this; + } + + /** + * 获取 注销范围 (此参数只在调用 StpUtil.logout(new SaLogoutParameter()) 时有效) + * + * @return / + */ + public SaLogoutRange getRange() { + return this.range; + } + + /** + * 设置 注销范围 (此参数只在调用 StpUtil.logout(new SaLogoutParameter()) 时有效) + * + * @param range / + * @return / + */ + public SaLogoutParameter setRange(SaLogoutRange range) { + this.range = range; + return this; + } + + /* + * toString + */ + @Override + public String toString() { + return "SaLoginParameter [" + + "deviceType=" + deviceType + + ", isKeepTokenSession=" + isKeepTokenSession + + ", isKeepFreezeOps=" + isKeepFreezeOps + + ", mode=" + mode + + ", range=" + range + + "]"; + } + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/enums/SaLogoutMode.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/enums/SaLogoutMode.java new file mode 100644 index 00000000..add2d509 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/enums/SaLogoutMode.java @@ -0,0 +1,41 @@ +/* + * 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.stp.parameter.enums; + +/** + * SaLogoutMode: 注销模式 + * + * @author click33 + * @since 1.41.0 + */ +public enum SaLogoutMode { + + /** + * 注销下线 + */ + LOGOUT, + + /** + * 踢人下线 + */ + KICKOUT, + + /** + * 顶人下线 + */ + REPLACED; + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/enums/SaLogoutRange.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/enums/SaLogoutRange.java new file mode 100644 index 00000000..7e87a41b --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/enums/SaLogoutRange.java @@ -0,0 +1,36 @@ +/* + * 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.stp.parameter.enums; + +/** + * SaLogoutMode: 注销范围 + * + * @author click33 + * @since 1.41.0 + */ +public enum SaLogoutRange { + + /** + * token 范围:只注销提供的 token 指向的会话 + */ + TOKEN, + + /** + * 账号范围:注销 token 指向的 loginId 会话 + */ + ACCOUNT + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/enums/SaReplacedMode.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/enums/SaReplacedMode.java new file mode 100644 index 00000000..6808f3e8 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/parameter/enums/SaReplacedMode.java @@ -0,0 +1,36 @@ +/* + * 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.stp.parameter.enums; + +/** + * 顶人下线的范围 + * + * @author click33 + * @since 1.41.0 + */ +public enum SaReplacedMode { + + /** + * 当前指定的设备类型端 + */ + CURR_DEVICE_TYPE, + + /** + * 所有设备类型端 + */ + ALL_DEVICE_TYPE + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java index f83ccf30..ca009e75 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTokenConsts.java @@ -74,7 +74,7 @@ public class SaTokenConsts { /** * 常量 key 标记: 在登录时,默认使用的设备类型 */ - public static final String DEFAULT_LOGIN_DEVICE = "default-device"; + public static final String DEFAULT_LOGIN_DEVICE_TYPE = "DEF"; /** * 常量 key 标记: 在封禁账号时,默认封禁的服务类型 diff --git a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/MySaTokenListener.java b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/MySaTokenListener.java index 494b516d..811e963b 100644 --- a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/MySaTokenListener.java +++ b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/MySaTokenListener.java @@ -1,7 +1,7 @@ package com.pj.satoken; import cn.dev33.satoken.listener.SaTokenListener; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; /** * Sa-Token 自定义侦听器的实现 diff --git a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpUserUtil.java b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpUserUtil.java index f64c77d7..5285729f 100644 --- a/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpUserUtil.java +++ b/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/satoken/StpUserUtil.java @@ -5,7 +5,7 @@ import cn.dev33.satoken.fun.SaFunction; import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.session.SaTerminalInfo; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.SaTokenInfo; import cn.dev33.satoken.stp.StpLogic; diff --git a/sa-token-demo/sa-token-demo-case/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-case/src/main/resources/application.yml index 051ea222..ed89db69 100644 --- a/sa-token-demo/sa-token-demo-case/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-case/src/main/resources/application.yml @@ -13,7 +13,7 @@ sa-token: # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) - is-share: true + is-share: false # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 diff --git a/sa-token-demo/sa-token-demo-device-lock/src/main/java/com/pj/test/LoginController.java b/sa-token-demo/sa-token-demo-device-lock/src/main/java/com/pj/test/LoginController.java index db9d53e2..8531eaf6 100644 --- a/sa-token-demo/sa-token-demo-device-lock/src/main/java/com/pj/test/LoginController.java +++ b/sa-token-demo/sa-token-demo-device-lock/src/main/java/com/pj/test/LoginController.java @@ -1,6 +1,6 @@ package com.pj.test; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaResult; import com.pj.util.DeviceLockCheckUtil; diff --git a/sa-token-demo/sa-token-demo-hutool-timed-cache/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-hutool-timed-cache/src/main/resources/application.yml index 3a2d6f57..1889895e 100644 --- a/sa-token-demo/sa-token-demo-hutool-timed-cache/src/main/resources/application.yml +++ b/sa-token-demo/sa-token-demo-hutool-timed-cache/src/main/resources/application.yml @@ -13,7 +13,7 @@ sa-token: # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) - is-share: true + is-share: false # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 diff --git a/sa-token-demo/sa-token-demo-test/pom.xml b/sa-token-demo/sa-token-demo-test/pom.xml index 64ff9c72..0ac983f4 100644 --- a/sa-token-demo/sa-token-demo-test/pom.xml +++ b/sa-token-demo/sa-token-demo-test/pom.xml @@ -60,7 +60,7 @@sa-token-redis-template ${sa-token.version} - +org.apache.commons diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/StpUserUtil.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/StpUserUtil.java index 278da594..82654893 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/StpUserUtil.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/StpUserUtil.java @@ -4,7 +4,7 @@ import cn.dev33.satoken.SaManager; import cn.dev33.satoken.fun.SaFunction; import cn.dev33.satoken.listener.SaTokenEventCenter; import cn.dev33.satoken.session.SaSession; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.SaTokenInfo; import cn.dev33.satoken.stp.StpLogic; diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/LoginController.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/LoginController.java index 36176d48..56529460 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/LoginController.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/LoginController.java @@ -1,6 +1,7 @@ package com.pj.test; import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.util.SaResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -20,6 +21,7 @@ public class LoginController { // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对 if("zhang".equals(name) && "123456".equals(pwd)) { StpUtil.login(10001); + StpUtil.getTokenSession(); return SaResult.ok("登录成功"); } return SaResult.error("登录失败"); @@ -47,7 +49,7 @@ public class LoginController { // 测试注销 ---- http://localhost:8081/acc/logout @RequestMapping("logout") public SaResult logout() { - StpUtil.logout(); + StpUtil.login(10001, SaLoginParameter.create().setIsConcurrent(false)); return SaResult.ok(); } diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java index 7852160e..81f1fba6 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java @@ -4,7 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckHttpDigest; import cn.dev33.satoken.annotation.SaCheckSign; import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.spring.SpringMVCUtil; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaResult; diff --git a/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForMixin.java b/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForMixin.java index 4a42583c..c21dc90f 100644 --- a/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForMixin.java +++ b/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForMixin.java @@ -23,7 +23,7 @@ import cn.dev33.satoken.exception.SaTokenException; import cn.dev33.satoken.jwt.error.SaJwtErrorCode; import cn.dev33.satoken.jwt.exception.SaJwtException; import cn.dev33.satoken.session.SaSession; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.SaTokenInfo; import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; diff --git a/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForStateless.java b/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForStateless.java index 22f70d2b..dd0136d5 100644 --- a/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForStateless.java +++ b/sa-token-plugin/sa-token-jwt/src/main/java/cn/dev33/satoken/jwt/StpLogicJwtForStateless.java @@ -22,7 +22,7 @@ import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.jwt.error.SaJwtErrorCode; import cn.dev33.satoken.jwt.exception.SaJwtException; import cn.dev33.satoken.listener.SaTokenEventCenter; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.SaTokenInfo; import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; diff --git a/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForMixinTest.java b/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForMixinTest.java index 63807d69..048fe26f 100644 --- a/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForMixinTest.java +++ b/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForMixinTest.java @@ -59,13 +59,13 @@ public class JwtForMixinTest { Assertions.assertTrue(StpUtil.isLogin()); Assertions.assertNotNull(token); // token不为null Assertions.assertEquals(StpUtil.getLoginIdAsLong(), 10001); // loginId=10001 - Assertions.assertEquals(StpUtil.getLoginDevice(), SaTokenConsts.DEFAULT_LOGIN_DEVICE); // 登录设备类型 + Assertions.assertEquals(StpUtil.getLoginDevice(), SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE); // 登录设备类型 // token 验证 JWT jwt = JWT.of(token); JSONObject payloads = jwt.getPayloads(); Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_ID), "10001"); // 账号 - Assertions.assertEquals(payloads.getStr(SaJwtUtil.DEVICE_TYPE), SaTokenConsts.DEFAULT_LOGIN_DEVICE); // 登录设备类型 + Assertions.assertEquals(payloads.getStr(SaJwtUtil.DEVICE_TYPE), SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE); // 登录设备类型 Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_TYPE), StpUtil.TYPE); // 账号类型 // db数据 验证 diff --git a/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForSimpleTest.java b/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForSimpleTest.java index c6aaf890..c655b701 100644 --- a/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForSimpleTest.java +++ b/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForSimpleTest.java @@ -54,7 +54,7 @@ public class JwtForSimpleTest { Assertions.assertTrue(StpUtil.isLogin()); Assertions.assertNotNull(token); // token不为null Assertions.assertEquals(StpUtil.getLoginIdAsLong(), 10001); // loginId=10001 - Assertions.assertEquals(StpUtil.getLoginDevice(), SaTokenConsts.DEFAULT_LOGIN_DEVICE); // 登录设备类型 + Assertions.assertEquals(StpUtil.getLoginDevice(), SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE); // 登录设备类型 // token 验证 JWT jwt = JWT.of(token); diff --git a/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForStatelessTest.java b/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForStatelessTest.java index 187cdf83..a9260458 100644 --- a/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForStatelessTest.java +++ b/sa-token-test/sa-token-jwt-test/src/test/java/com/pj/test/JwtForStatelessTest.java @@ -55,13 +55,13 @@ public class JwtForStatelessTest { Assertions.assertTrue(StpUtil.isLogin()); Assertions.assertNotNull(token); // token不为null Assertions.assertEquals(StpUtil.getLoginIdAsLong(), 10001); // loginId=10001 - Assertions.assertEquals(StpUtil.getLoginDevice(), SaTokenConsts.DEFAULT_LOGIN_DEVICE); // 登录设备类型 + Assertions.assertEquals(StpUtil.getLoginDevice(), SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE); // 登录设备类型 // token 验证 JWT jwt = JWT.of(token); JSONObject payloads = jwt.getPayloads(); Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_ID), "10001"); // 账号 - Assertions.assertEquals(payloads.getStr(SaJwtUtil.DEVICE_TYPE), SaTokenConsts.DEFAULT_LOGIN_DEVICE); // 登录设备类型 + Assertions.assertEquals(payloads.getStr(SaJwtUtil.DEVICE_TYPE), SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE); // 登录设备类型 Assertions.assertEquals(payloads.getStr(SaJwtUtil.LOGIN_TYPE), StpUtil.TYPE); // 账号类型 // 时间 diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/stp/TokenInfoTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/stp/TokenInfoTest.java index a1a9ba36..414eb380 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/stp/TokenInfoTest.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/stp/TokenInfoTest.java @@ -15,7 +15,7 @@ */ package cn.dev33.satoken.core.stp; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.SaTokenInfo; import cn.dev33.satoken.util.SaTokenConsts; import org.junit.jupiter.api.Assertions; @@ -83,7 +83,7 @@ public class TokenInfoTest { .create() .setTimeout(-1); Assertions.assertEquals(loginParameter.getCookieTimeout(), Integer.MAX_VALUE); - Assertions.assertEquals(loginParameter.getDeviceOrDefault(), SaTokenConsts.DEFAULT_LOGIN_DEVICE); + Assertions.assertEquals(loginParameter.getDeviceTypeOrDefault(), SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE); } } diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/springboot/BasicsTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/springboot/BasicsTest.java index b2672ae5..63251d0d 100644 --- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/springboot/BasicsTest.java +++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/springboot/BasicsTest.java @@ -26,7 +26,7 @@ import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.spring.SpringMVCUtil; import cn.dev33.satoken.spring.pathmatch.SaPathMatcherHolder; import cn.dev33.satoken.stp.SaLoginConfig; -import cn.dev33.satoken.stp.SaLoginParameter; +import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.util.SaTokenConsts; @@ -102,11 +102,11 @@ public class BasicsTest { Assertions.assertNotNull(token); Assertions.assertEquals(token, StpUtil.getTokenValueNotCut()); Assertions.assertEquals(token, StpUtil.getTokenValueByLoginId(10001)); - Assertions.assertEquals(token, StpUtil.getTokenValueByLoginId(10001, SaTokenConsts.DEFAULT_LOGIN_DEVICE)); + Assertions.assertEquals(token, StpUtil.getTokenValueByLoginId(10001, SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE)); // token 队列 ListtokenList = StpUtil.getTokenValueListByLoginId(10001); - List tokenList2 = StpUtil.getTokenValueListByLoginId(10001, SaTokenConsts.DEFAULT_LOGIN_DEVICE); + List tokenList2 = StpUtil.getTokenValueListByLoginId(10001, SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE); Assertions.assertEquals(token, tokenList.get(tokenList.size() - 1)); Assertions.assertEquals(token, tokenList2.get(tokenList.size() - 1)); @@ -119,7 +119,7 @@ public class BasicsTest { Assertions.assertEquals(StpUtil.getLoginIdAsString(), "10001"); // loginId=10001 Assertions.assertEquals(StpUtil.getLoginId(), "10001"); // loginId=10001 Assertions.assertEquals(StpUtil.getLoginIdDefaultNull(), "10001"); // loginId=10001 - Assertions.assertEquals(StpUtil.getLoginDevice(), SaTokenConsts.DEFAULT_LOGIN_DEVICE); // 登录设备类型 + Assertions.assertEquals(StpUtil.getLoginDevice(), SaTokenConsts.DEFAULT_LOGIN_DEVICE_TYPE); // 登录设备类型 // db数据 验证 // token存在