From dcb630c0828ede8b639b23598a6e7a5da825a1e8 Mon Sep 17 00:00:00 2001 From: memorylkf <312904636@qq.com> Date: Fri, 19 Dec 2025 16:12:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:[=E7=99=BB=E5=BD=95]=20=E5=8F=AA=E5=85=81?= =?UTF-8?q?=E8=AE=B8=E5=90=8C=E6=97=B61=E4=B8=AA=E5=9C=B0=E6=96=B9?= =?UTF-8?q?=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/hxhq/auth/controller/TokenController.java | 2 +- .../main/java/com/hxhq/auth/form/LoginBody.java | 13 +++++++++++ .../com/hxhq/auth/service/SysLoginService.java | 26 ++++++++++++++++++++- hxhq-auth/src/main/resources/bootstrap.yml | 4 ++++ .../hxhq/common/core/constant/CacheConstants.java | 5 ++++ .../com/hxhq/common/security/auth/AuthLogic.java | 7 +++++- .../hxhq/common/security/service/TokenService.java | 27 +++++++++++++++++++--- .../hxhq-system/src/main/resources/bootstrap.yml | 4 ++++ 8 files changed, 82 insertions(+), 6 deletions(-) diff --git a/hxhq-auth/src/main/java/com/hxhq/auth/controller/TokenController.java b/hxhq-auth/src/main/java/com/hxhq/auth/controller/TokenController.java index 3f21e57..2e2cb67 100644 --- a/hxhq-auth/src/main/java/com/hxhq/auth/controller/TokenController.java +++ b/hxhq-auth/src/main/java/com/hxhq/auth/controller/TokenController.java @@ -36,7 +36,7 @@ public class TokenController public R login(@RequestBody LoginBody form) { // 用户登录 - LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword()); + LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword(),form.getForce()); // 获取登录token return R.ok(tokenService.createToken(userInfo)); } diff --git a/hxhq-auth/src/main/java/com/hxhq/auth/form/LoginBody.java b/hxhq-auth/src/main/java/com/hxhq/auth/form/LoginBody.java index e07abe1..0b7bc6a 100644 --- a/hxhq-auth/src/main/java/com/hxhq/auth/form/LoginBody.java +++ b/hxhq-auth/src/main/java/com/hxhq/auth/form/LoginBody.java @@ -17,6 +17,11 @@ public class LoginBody */ private String password; + /** + * 强制登录 + */ + private Boolean force; + public String getUsername() { return username; @@ -36,4 +41,12 @@ public class LoginBody { this.password = password; } + + public Boolean getForce() { + return force; + } + + public void setForce(Boolean force) { + this.force = force; + } } diff --git a/hxhq-auth/src/main/java/com/hxhq/auth/service/SysLoginService.java b/hxhq-auth/src/main/java/com/hxhq/auth/service/SysLoginService.java index 2cd6192..1c5239e 100644 --- a/hxhq-auth/src/main/java/com/hxhq/auth/service/SysLoginService.java +++ b/hxhq-auth/src/main/java/com/hxhq/auth/service/SysLoginService.java @@ -1,6 +1,7 @@ package com.hxhq.auth.service; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.hxhq.common.core.constant.CacheConstants; import com.hxhq.common.core.constant.Constants; @@ -40,9 +41,15 @@ public class SysLoginService private RedisService redisService; /** + * 是否允许账户多终端同时登录(true允许 false不允许) + */ + @Value("${token.soloLogin}") + private boolean soloLogin; + + /** * 登录 */ - public LoginUser login(String username, String password) + public LoginUser login(String username, String password,Boolean force) { // 用户名或密码为空 错误 if (StringUtils.isAnyBlank(username, password)) @@ -81,6 +88,23 @@ public class SysLoginService LoginUser userInfo = userResult.getData(); SysUser user = userResult.getData().getSysUser(); + + if (!soloLogin) + { + // 如果用户不允许多终端同时登录,清除缓存信息 + String userIdKey = CacheConstants.LOGIN_USERID_KEY + user.getUserId(); + String userKey = redisService.getCacheObject(userIdKey); + if (StringUtils.isNotEmpty(userKey)) + { + if(force==null || !force){ + throw new ServiceException("exists"); + }else{ + redisService.deleteObject(userIdKey); + redisService.deleteObject(userKey); + } + } + } + if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) { recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除"); diff --git a/hxhq-auth/src/main/resources/bootstrap.yml b/hxhq-auth/src/main/resources/bootstrap.yml index 1da844e..5089d60 100644 --- a/hxhq-auth/src/main/resources/bootstrap.yml +++ b/hxhq-auth/src/main/resources/bootstrap.yml @@ -23,3 +23,7 @@ spring: # 共享配置 shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# token配置 +token: + # 是否允许账户多终端同时登录(true允许 false不允许) + soloLogin: false \ No newline at end of file diff --git a/hxhq-common/hxhq-common-core/src/main/java/com/hxhq/common/core/constant/CacheConstants.java b/hxhq-common/hxhq-common-core/src/main/java/com/hxhq/common/core/constant/CacheConstants.java index 4bd3970..b7fa062 100644 --- a/hxhq-common/hxhq-common-core/src/main/java/com/hxhq/common/core/constant/CacheConstants.java +++ b/hxhq-common/hxhq-common-core/src/main/java/com/hxhq/common/core/constant/CacheConstants.java @@ -56,4 +56,9 @@ public class CacheConstants * 登录IP黑名单 cache key */ public static final String SYS_LOGIN_BLACKIPLIST = SYS_CONFIG_KEY + "sys.login.blackIPList"; + + /** + * 登录用户编号 redis key + */ + public static final String LOGIN_USERID_KEY = "login_userid:"; } diff --git a/hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/auth/AuthLogic.java b/hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/auth/AuthLogic.java index 7dada11..470a264 100644 --- a/hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/auth/AuthLogic.java +++ b/hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/auth/AuthLogic.java @@ -51,7 +51,12 @@ public class AuthLogic */ public void logoutByToken(String token) { - tokenService.delLoginUser(token); + LoginUser loginUser = getLoginUser(token); + if(loginUser!=null){ + tokenService.delLoginUser(token,loginUser.getUserid()); + }else{ + tokenService.delLoginUser(token,null); + } } /** diff --git a/hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/service/TokenService.java b/hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/service/TokenService.java index 11f5b81..ef306ae 100644 --- a/hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/service/TokenService.java +++ b/hxhq-common/hxhq-common-security/src/main/java/com/hxhq/common/security/service/TokenService.java @@ -9,6 +9,7 @@ import com.hxhq.common.security.utils.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.hxhq.common.core.constant.CacheConstants; import com.hxhq.common.core.constant.SecurityConstants; @@ -44,6 +45,12 @@ public class TokenService private final static Long TOKEN_REFRESH_THRESHOLD_MINUTES = CacheConstants.REFRESH_TIME * MILLIS_MINUTE; /** + * 是否允许账户多终端同时登录(true允许 false不允许) + */ + @Value("${token.soloLogin}") + private boolean soloLogin; + + /** * 创建令牌 */ public Map createToken(LoginUser loginUser) @@ -130,13 +137,16 @@ public class TokenService /** * 删除用户缓存信息 */ - public void delLoginUser(String token) + public void delLoginUser(String token, Long userId) { - if (StringUtils.isNotEmpty(token)) - { + if (StringUtils.isNotEmpty(token)) { String userkey = JwtUtils.getUserKey(token); redisService.deleteObject(getTokenKey(userkey)); } + if (!soloLogin && StringUtils.isNotNull(userId)) { + String userIdKey = getUserIdKey(userId); + redisService.deleteObject(userIdKey); + } } /** @@ -166,10 +176,21 @@ public class TokenService // 根据uuid将loginUser缓存 String userKey = getTokenKey(loginUser.getToken()); redisService.setCacheObject(userKey, loginUser, TOKEN_EXPIRE_TIME, TimeUnit.MINUTES); + if (!soloLogin) + { + // 缓存用户唯一标识,防止同一帐号,同时登录 + String userIdKey = getUserIdKey(loginUser.getSysUser().getUserId()); + redisService.setCacheObject(userIdKey, userKey, TOKEN_EXPIRE_TIME, TimeUnit.MINUTES); + } } private String getTokenKey(String token) { return ACCESS_TOKEN + token; } + + private String getUserIdKey(Long userId) + { + return CacheConstants.LOGIN_USERID_KEY + userId; + } } \ No newline at end of file diff --git a/hxhq-modules/hxhq-system/src/main/resources/bootstrap.yml b/hxhq-modules/hxhq-system/src/main/resources/bootstrap.yml index db0af42..60d0a80 100644 --- a/hxhq-modules/hxhq-system/src/main/resources/bootstrap.yml +++ b/hxhq-modules/hxhq-system/src/main/resources/bootstrap.yml @@ -23,3 +23,7 @@ spring: # 共享配置 shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# token配置 +token: + # 是否允许账户多终端同时登录(true允许 false不允许) + soloLogin: false \ No newline at end of file