refactor: 重命名 SaRepeatLoginsMode -> SaReplacedLoginExitMode

This commit is contained in:
click33
2026-03-02 04:59:09 +08:00
parent 466c215506
commit 22302760c8
6 changed files with 69 additions and 55 deletions

View File

@@ -17,7 +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.SaReplacedLoginExitMode;
import cn.dev33.satoken.stp.parameter.enums.SaReplacedRange;
import cn.dev33.satoken.util.SaFoxUtil;
@@ -66,9 +66,9 @@ public class SaTokenConfig implements Serializable {
private Boolean isShare = false;
/**
* isConcurrent=false 时,多客户端登录时的处理策略
* isConcurrent=false 时,决定新旧设备谁将放弃会话 (OLD_DEVICE=旧设备下线,新设备登录成功, NEW_DEVICE=新设备登录失败,旧设备维持在线)
*/
private SaRepeatLoginsMode repeatLoginsMode = SaRepeatLoginsMode.KICKOUT;
private SaReplacedLoginExitMode replacedLoginExitMode = SaReplacedLoginExitMode.OLD_DEVICE;
/**
* 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端, ALL_DEVICE_TYPE=所有设备类型端)
@@ -720,18 +720,18 @@ public class SaTokenConfig implements Serializable {
}
/**
* @return 不允许并发登录时,重复登录处理策略
* @return 在 isConcurrent=false 时,决定新旧设备谁将放弃会话 (OLD_DEVICE=旧设备下线,新设备登录成功, NEW_DEVICE=新设备登录失败,旧设备维持在线)
*/
public SaRepeatLoginsMode getRepeatLoginsMode() {
return repeatLoginsMode;
public SaReplacedLoginExitMode getReplacedLoginExitMode() {
return replacedLoginExitMode;
}
/**
* @param repeatLoginsMode 不允许并发登录时,重复登录处理策略
* @param replacedLoginExitMode 在 isConcurrent=false 时,决定新旧设备谁将放弃会话 (OLD_DEVICE=旧设备下线,新设备登录成功, NEW_DEVICE=新设备登录失败,旧设备维持在线)
* @return 对象自身
*/
public SaTokenConfig setRepeatLoginsMode(SaRepeatLoginsMode repeatLoginsMode) {
this.repeatLoginsMode = repeatLoginsMode;
public SaTokenConfig setReplacedLoginExitMode(SaReplacedLoginExitMode replacedLoginExitMode) {
this.replacedLoginExitMode = replacedLoginExitMode;
return this;
}
@@ -882,7 +882,7 @@ public class SaTokenConfig implements Serializable {
+ ", isConcurrent=" + isConcurrent
+ ", isShare=" + isShare
+ ", replacedRange=" + replacedRange
+ ", repeatLoginsMode=" + repeatLoginsMode
+ ", replacedLoginExitMode=" + replacedLoginExitMode
+ ", maxLoginCount=" + maxLoginCount
+ ", overflowLogoutMode=" + overflowLogoutMode
+ ", maxTryTimes=" + maxTryTimes

View File

@@ -80,7 +80,7 @@ public interface SaErrorCode {
/** 更改 Token 指向的 账号Id 时账号Id值为空 */
int CODE_11003 = 11003;
/** 当前账号已经登录 */
/** 登录失败:当前账号已在其它客户端登录 */
int CODE_11004 = 11004;
/** 未能读取到有效Token */

View File

@@ -36,7 +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.SaReplacedLoginExitMode;
import cn.dev33.satoken.stp.parameter.enums.SaReplacedRange;
import cn.dev33.satoken.strategy.SaStrategy;
import cn.dev33.satoken.util.SaFoxUtil;
@@ -539,27 +539,25 @@ public class StpLogic {
protected String distUsableToken(Object id, SaLoginParameter loginParameter) {
// 1、获取全局配置的 isConcurrent 参数
// 如果配置为:不允许一个账号多地同时登录,则需要根据配置选择:
// 一.将这个账号的历史登录会话标记为:被顶下线
// 二.提示错误并拒绝本次登录
if( ! loginParameter.getIsConcurrent()) {
if (loginParameter.getRepeatLoginsMode() == SaRepeatLoginsMode.KICKOUT){
// 如果配置为:不允许一个账号多地同时登录,则需要根据配置选择:
// 一.将这个账号的历史登录会话标记为:被顶下线
// 二.提示错误并拒绝本次登录
if (loginParameter.getReplacedLoginExitMode() == SaReplacedLoginExitMode.OLD_DEVICE){
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){
} else if (loginParameter.getReplacedLoginExitMode() == SaReplacedLoginExitMode.NEW_DEVICE){
List<SaTerminalInfo> terminalListByLoginId = getTerminalListByLoginId(id);
// 只有当存在有效会话时才拒绝登录
// 只有当存在有效会话时才拒绝登录
boolean hasActiveSession = terminalListByLoginId.stream()
.anyMatch(terminal -> isValidToken(terminal.getTokenValue()));
if (hasActiveSession) {
throw new SaTokenException("当前账号已在其客户端登录").setCode(SaErrorCode.CODE_11004);
throw new SaTokenException("登录失败:当前账号已在其客户端登录").setCode(SaErrorCode.CODE_11004);
}
}
}

View File

@@ -21,7 +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.SaReplacedLoginExitMode;
import cn.dev33.satoken.stp.parameter.enums.SaReplacedRange;
import cn.dev33.satoken.util.SaTokenConsts;
@@ -112,9 +112,9 @@ public class SaLoginParameter {
private Boolean isWriteHeader;
/**
* isConcurrent=false 时,多客户端登录时的处理策略
* isConcurrent=false 时,决定新旧设备谁将放弃会话
*/
private SaRepeatLoginsMode repeatLoginsMode;
private SaReplacedLoginExitMode replacedLoginExitMode;
/**
* 当 isConcurrent=false 时,顶人下线的范围 (CURR_DEVICE_TYPE=当前指定的设备类型端, ALL_DEVICE_TYPE=所有设备类型端)
@@ -164,7 +164,7 @@ public class SaLoginParameter {
this.replacedRange = config.getReplacedRange();
this.overflowLogoutMode = config.getOverflowLogoutMode();
this.rightNowCreateTokenSession = config.getRightNowCreateTokenSession();
this.repeatLoginsMode = config.getRepeatLoginsMode();
this.replacedLoginExitMode = config.getReplacedLoginExitMode();
this.setupCookieConfig(cookie -> {
SaCookieConfig gCookie = config.getCookie();
@@ -577,19 +577,21 @@ public class SaLoginParameter {
/**
* 获取:多客户端登录时的处理策略
* @return 多客户端登录时的处理策略
* 获取:在 isConcurrent=false 时,决定新旧设备谁将放弃会话 (OLD_DEVICE=旧设备下线,新设备登录成功, NEW_DEVICE=新设备登录失败,旧设备维持在线)
* @return /
*/
public SaRepeatLoginsMode getRepeatLoginsMode() {
return repeatLoginsMode;
public SaReplacedLoginExitMode getReplacedLoginExitMode() {
return replacedLoginExitMode;
}
/**
* 设置:多客户端登录时的处理策略
* @param repeatLoginsMode 多客户端登录时的处理策略
* 设置:在 isConcurrent=false 时,决定新旧设备谁将放弃会话 (OLD_DEVICE=旧设备下线,新设备登录成功, NEW_DEVICE=新设备登录失败,旧设备维持在线)
* @param replacedLoginExitMode /
* @return 对象自身
*/
public void setRepeatLoginsMode(SaRepeatLoginsMode repeatLoginsMode) {
this.repeatLoginsMode = repeatLoginsMode;
public SaLoginParameter setReplacedLoginExitMode(SaReplacedLoginExitMode replacedLoginExitMode) {
this.replacedLoginExitMode = replacedLoginExitMode;
return this;
}
/*
@@ -601,7 +603,7 @@ public class SaLoginParameter {
+ "deviceType=" + deviceType
+ ", deviceId=" + deviceId
+ ", replacedRange=" + replacedRange
+ ", repeatLoginsMode=" + repeatLoginsMode
+ ", replacedLoginExitMode=" + replacedLoginExitMode
+ ", overflowLogoutMode=" + overflowLogoutMode
+ ", isLastingCookie=" + isLastingCookie
+ ", timeout=" + timeout

View File

@@ -1,21 +0,0 @@
package cn.dev33.satoken.stp.parameter.enums;
/**
* SaRepeatLoginsMode: 重复登录模式
* @author 石泽旭
* @since 1.44.0
*/
public enum SaRepeatLoginsMode {
/**
* 将旧会话踢出
*/
KICKOUT,
/**
* 拦截新的登录会话
*/
INTERCEPT
}

View File

@@ -0,0 +1,35 @@
/*
* 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;
/**
* 在 isConcurrent=false 时,决定新旧设备谁将放弃会话
* @author 石泽旭
* @since 1.44.0
*/
public enum SaReplacedLoginExitMode {
/**
* 旧设备下线,新设备登录成功
*/
OLD_DEVICE,
/**
* 新设备登录失败,旧设备维持在线
*/
NEW_DEVICE
}