From e73e976d683b5b8ebcf8785edc3fac39d1927b4d Mon Sep 17 00:00:00 2001 From: gaoqr <13665037151@163.com> Date: Tue, 10 Mar 2026 10:39:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=B8=AA=E4=BA=BA=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E4=BF=AE=E6=94=B9=E5=AF=86=E7=A0=81=E3=80=81=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=AB=AF=E9=87=8D=E7=BD=AE=E5=AF=86=E7=A0=81=E5=90=8E?= =?UTF-8?q?=E7=94=A8=E6=88=B7token=E5=A4=B1=E6=95=88=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/oauth2/OAuth2TokenService.java | 6 +++ .../oauth2/OAuth2TokenServiceImpl.java | 38 +++++++++++-------- .../service/user/AdminUserServiceImpl.java | 24 ++++++++++++ 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/oauth2/OAuth2TokenService.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/oauth2/OAuth2TokenService.java index 7facde439..6acc06797 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/oauth2/OAuth2TokenService.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/oauth2/OAuth2TokenService.java @@ -91,4 +91,10 @@ public interface OAuth2TokenService { */ PageResult getAccessTokenPage(OAuth2AccessTokenPageReqVO reqVO); + + /** + * 清除userId对应用户的token + * @param userId + */ + void kickOut(Long userId); } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/oauth2/OAuth2TokenServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/oauth2/OAuth2TokenServiceImpl.java index e2fb8e34a..223054939 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/oauth2/OAuth2TokenServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/oauth2/OAuth2TokenServiceImpl.java @@ -29,7 +29,6 @@ import org.springframework.transaction.annotation.Transactional; import jakarta.annotation.Resource; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -240,9 +239,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { // 记录到 Redis 中 oauth2AccessTokenRedisDAO.set(accessTokenDO); // 异步踢出其他token - CompletableFuture.runAsync(() -> { - kickOut(userId, currentToken); - }).exceptionally(e -> { + CompletableFuture.runAsync(() -> kickOut(userId, currentToken)).exceptionally(e -> { log.error("[OAuth2TokenServiceImpl] redis 清空token失败, 用户id:{}, 异常:{}", userId, e); return null; }); @@ -256,22 +253,17 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { * @param currentToken */ public void kickOut(Long userId, String currentToken) { - List matchKeys = new ArrayList<>(); Cursor cursor = oauth2AccessTokenRedisDAO.scan(); while (cursor.hasNext()) { - matchKeys.add(cursor.next()); - } - cursor.close(); - if (CollUtil.isNotEmpty(matchKeys)) { - for (String key : matchKeys) { - // 获取key下的用户信息 - OAuth2AccessTokenDO oAuth2AccessTokenDO = oauth2AccessTokenRedisDAO.getWithKey(key); - if (ObjectUtil.equal(userId, oAuth2AccessTokenDO.getUserId()) && !StringUtils.equals(currentToken, oAuth2AccessTokenDO.getAccessToken()) && Boolean.FALSE.equals(oAuth2AccessTokenDO.getIsSupAdmin())) { - // 用户id匹配、非当次登录token、非超管 -> 删除redis中的token缓存 - oauth2AccessTokenRedisDAO.deleteWithKey(key); - } + String key = cursor.next(); + // 获取key下的用户信息 + OAuth2AccessTokenDO oAuth2AccessTokenDO = oauth2AccessTokenRedisDAO.getWithKey(key); + if (ObjectUtil.equal(userId, oAuth2AccessTokenDO.getUserId()) && !StringUtils.equals(currentToken, oAuth2AccessTokenDO.getAccessToken()) && Boolean.FALSE.equals(oAuth2AccessTokenDO.getIsSupAdmin())) { + // 用户id匹配、非当次登录token、非超管 -> 删除redis中的token缓存 + oauth2AccessTokenRedisDAO.deleteWithKey(key); } } + cursor.close(); } @@ -284,4 +276,18 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { return IdUtil.fastSimpleUUID(); } + @Override + public void kickOut(Long userId) { + Cursor cursor = oauth2AccessTokenRedisDAO.scan(); + while (cursor.hasNext()) { + String key = cursor.next(); + // 获取key下的用户信息 + OAuth2AccessTokenDO oAuth2AccessTokenDO = oauth2AccessTokenRedisDAO.getWithKey(key); + if (ObjectUtil.equal(userId, oAuth2AccessTokenDO.getUserId())) { + // 用户id匹配 -> 删除redis中的token缓存 + oauth2AccessTokenRedisDAO.deleteWithKey(key); + } + } + cursor.close(); + } } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/user/AdminUserServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/user/AdminUserServiceImpl.java index fed43a66b..a63f98c53 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/user/AdminUserServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/user/AdminUserServiceImpl.java @@ -47,6 +47,7 @@ import com.cf.imes.module.system.enums.logger.LoginResultEnum; import com.cf.imes.module.system.enums.sms.SmsSceneEnum; import com.cf.imes.module.system.service.dept.DeptService; import com.cf.imes.module.system.service.logger.LoginLogService; +import com.cf.imes.module.system.service.oauth2.OAuth2TokenService; import com.cf.imes.module.system.service.organ.OrganService; import com.cf.imes.module.system.service.permission.PermissionService; import com.cf.imes.module.system.service.sms.SmsCodeService; @@ -68,6 +69,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.*; +import java.util.concurrent.CompletableFuture; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -119,6 +121,9 @@ public class AdminUserServiceImpl implements AdminUserService { @Resource private I18nUtils i18nUtils; + @Resource + private OAuth2TokenService oAuth2TokenService; + // 定义密码校验的正则表达式 private static final String LENGTH_PATTERN = ".{8,}"; private static final String UPPER_LETTER_PATTERN = ".*[A-Z].*"; @@ -261,6 +266,22 @@ public class AdminUserServiceImpl implements AdminUserService { AdminUserDO updateObj = new AdminUserDO().setId(id); updateObj.setPassword(encodePassword(reqVO.getNewPassword())); // 加密密码 userMapper.updateById(updateObj); + + // 踢出登录 + asyncKickOut(id); + } + + /** + * 异步踢出登录 + * + * @param userId + */ + private void asyncKickOut(Long userId) { + // 踢出登录 + CompletableFuture.runAsync(() -> oAuth2TokenService.kickOut(userId)).exceptionally(e -> { + log.error("[AdminUserServiceImpl] redis 清空token失败, 用户id:{}, 异常:{}", userId, e); + return null; + }); } @Override @@ -287,6 +308,9 @@ public class AdminUserServiceImpl implements AdminUserService { validatePassword(password); updateObj.setPassword(encodePassword(password)); // 加密密码 userMapper.updateById(updateObj); + + // 踢出登录 + asyncKickOut(id); } @Override