mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-08-20 00:44:30 +08:00
Pre Merge pull request !349 from 石泽旭/dev
This commit is contained in:
commit
c6e19e09f1
@ -17,6 +17,7 @@ package cn.dev33.satoken.config;
|
||||
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaLogoutMode;
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaLogoutRange;
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaRepeatLoginsMode;
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaReplacedRange;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
@ -64,6 +65,11 @@ public class SaTokenConfig implements Serializable {
|
||||
*/
|
||||
private Boolean isShare = false;
|
||||
|
||||
/**
|
||||
* 当 isConcurrent=false 时,多客户端登录时的处理策略
|
||||
*/
|
||||
private SaRepeatLoginsMode repeatLoginsMode = SaRepeatLoginsMode.KICKOUT;
|
||||
|
||||
/**
|
||||
* 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端, ALL_DEVICE_TYPE=所有设备类型端)
|
||||
*/
|
||||
@ -713,6 +719,22 @@ public class SaTokenConfig implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 不允许并发登录时,重复登录处理策略
|
||||
*/
|
||||
public SaRepeatLoginsMode getRepeatLoginsMode() {
|
||||
return repeatLoginsMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repeatLoginsMode 不允许并发登录时,重复登录处理策略
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaTokenConfig setRepeatLoginsMode(SaRepeatLoginsMode repeatLoginsMode) {
|
||||
this.repeatLoginsMode = repeatLoginsMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端 ALL_DEVICE_TYPE=所有设备类型端)
|
||||
*
|
||||
@ -860,6 +882,7 @@ public class SaTokenConfig implements Serializable {
|
||||
+ ", isConcurrent=" + isConcurrent
|
||||
+ ", isShare=" + isShare
|
||||
+ ", replacedRange=" + replacedRange
|
||||
+ ", repeatLoginsMode=" + repeatLoginsMode
|
||||
+ ", maxLoginCount=" + maxLoginCount
|
||||
+ ", overflowLogoutMode=" + overflowLogoutMode
|
||||
+ ", maxTryTimes=" + maxTryTimes
|
||||
|
@ -80,6 +80,9 @@ public interface SaErrorCode {
|
||||
/** 更改 Token 指向的 账号Id 时,账号Id值为空 */
|
||||
int CODE_11003 = 11003;
|
||||
|
||||
/** 当前账号已经登录 */
|
||||
int CODE_11004 = 11004;
|
||||
|
||||
/** 未能读取到有效Token */
|
||||
int CODE_11011 = 11011;
|
||||
|
||||
|
@ -36,6 +36,7 @@ import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import cn.dev33.satoken.stp.parameter.SaLogoutParameter;
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaLogoutMode;
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaLogoutRange;
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaRepeatLoginsMode;
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaReplacedRange;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
@ -538,13 +539,27 @@ public class StpLogic {
|
||||
protected String distUsableToken(Object id, SaLoginParameter loginParameter) {
|
||||
|
||||
// 1、获取全局配置的 isConcurrent 参数
|
||||
// 如果配置为:不允许一个账号多地同时登录,则需要先将这个账号的历史登录会话标记为:被顶下线
|
||||
// 如果配置为:不允许一个账号多地同时登录,则需要根据配置选择:
|
||||
// 一.将这个账号的历史登录会话标记为:被顶下线
|
||||
// 二.提示错误并拒绝本次登录
|
||||
if( ! loginParameter.getIsConcurrent()) {
|
||||
if(loginParameter.getReplacedRange() == SaReplacedRange.CURR_DEVICE_TYPE) {
|
||||
replaced(id, loginParameter.getDeviceType());
|
||||
}
|
||||
if(loginParameter.getReplacedRange() == SaReplacedRange.ALL_DEVICE_TYPE) {
|
||||
replaced(id, createSaLogoutParameter());
|
||||
if (loginParameter.getRepeatLoginsMode() == SaRepeatLoginsMode.KICKOUT){
|
||||
if(loginParameter.getReplacedRange() == SaReplacedRange.CURR_DEVICE_TYPE) {
|
||||
replaced(id, loginParameter.getDeviceType());
|
||||
}
|
||||
if(loginParameter.getReplacedRange() == SaReplacedRange.ALL_DEVICE_TYPE) {
|
||||
replaced(id, createSaLogoutParameter());
|
||||
}
|
||||
} else if (loginParameter.getRepeatLoginsMode() == SaRepeatLoginsMode.INTERCEPT){
|
||||
List<SaTerminalInfo> terminalListByLoginId = getTerminalListByLoginId(id);
|
||||
// 只有当存在有效的会话时才拒绝登录
|
||||
boolean hasActiveSession = terminalListByLoginId.stream()
|
||||
.anyMatch(terminal -> isValidToken(terminal.getTokenValue()));
|
||||
|
||||
if (hasActiveSession) {
|
||||
throw new SaTokenException("当前账号已在其他客户端登录").setCode(SaErrorCode.CODE_11004);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.fun.SaParamFunction;
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaLogoutMode;
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaRepeatLoginsMode;
|
||||
import cn.dev33.satoken.stp.parameter.enums.SaReplacedRange;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
|
||||
@ -110,6 +111,11 @@ public class SaLoginParameter {
|
||||
*/
|
||||
private Boolean isWriteHeader;
|
||||
|
||||
/**
|
||||
* 当 isConcurrent=false 时,多客户端登录时的处理策略
|
||||
*/
|
||||
private SaRepeatLoginsMode repeatLoginsMode;
|
||||
|
||||
/**
|
||||
* 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端, ALL_DEVICE_TYPE=所有设备类型端)
|
||||
*/
|
||||
@ -158,6 +164,7 @@ public class SaLoginParameter {
|
||||
this.replacedRange = config.getReplacedRange();
|
||||
this.overflowLogoutMode = config.getOverflowLogoutMode();
|
||||
this.rightNowCreateTokenSession = config.getRightNowCreateTokenSession();
|
||||
this.repeatLoginsMode = config.getRepeatLoginsMode();
|
||||
|
||||
this.setupCookieConfig(cookie -> {
|
||||
SaCookieConfig gCookie = config.getCookie();
|
||||
@ -568,6 +575,23 @@ public class SaLoginParameter {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取:多客户端登录时的处理策略
|
||||
* @return 多客户端登录时的处理策略
|
||||
*/
|
||||
public SaRepeatLoginsMode getRepeatLoginsMode() {
|
||||
return repeatLoginsMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:多客户端登录时的处理策略
|
||||
* @param repeatLoginsMode 多客户端登录时的处理策略
|
||||
*/
|
||||
public void setRepeatLoginsMode(SaRepeatLoginsMode repeatLoginsMode) {
|
||||
this.repeatLoginsMode = repeatLoginsMode;
|
||||
}
|
||||
|
||||
/*
|
||||
* toString
|
||||
*/
|
||||
@ -577,6 +601,7 @@ public class SaLoginParameter {
|
||||
+ "deviceType=" + deviceType
|
||||
+ ", deviceId=" + deviceId
|
||||
+ ", replacedRange=" + replacedRange
|
||||
+ ", repeatLoginsMode=" + repeatLoginsMode
|
||||
+ ", overflowLogoutMode=" + overflowLogoutMode
|
||||
+ ", isLastingCookie=" + isLastingCookie
|
||||
+ ", timeout=" + timeout
|
||||
|
@ -0,0 +1,21 @@
|
||||
package cn.dev33.satoken.stp.parameter.enums;
|
||||
|
||||
/**
|
||||
* SaRepeatLoginsMode: 重复登录模式
|
||||
* @author 石泽旭
|
||||
* @since 1.44.0
|
||||
*/
|
||||
public enum SaRepeatLoginsMode {
|
||||
|
||||
/**
|
||||
* 将旧会话踢出
|
||||
*/
|
||||
KICKOUT,
|
||||
|
||||
/**
|
||||
* 拦截新的登录会话
|
||||
*/
|
||||
INTERCEPT
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user