|
@@ -3,24 +3,25 @@ package com.usky.system.service.util;
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.ruoyi.common.core.constant.CacheConstants;
|
|
|
import com.ruoyi.common.core.constant.Constants;
|
|
|
-import com.ruoyi.common.core.utils.ServletUtils;
|
|
|
import com.ruoyi.common.core.utils.StringUtils;
|
|
|
-import com.ruoyi.common.core.utils.ip.IpUtils;
|
|
|
import com.usky.common.core.util.SpringContextUtils;
|
|
|
+import com.usky.common.log.aspect.AddressUtils;
|
|
|
+import com.usky.common.redis.core.RedisService;
|
|
|
import com.usky.system.domain.MceRequestVO;
|
|
|
import com.usky.system.domain.SysLogininfor;
|
|
|
import com.usky.system.domain.SysUser;
|
|
|
import com.usky.system.mapper.SysUserMapper;
|
|
|
+import com.usky.system.model.LoginUser;
|
|
|
import com.usky.system.service.ISysLogininforService;
|
|
|
-import com.usky.system.service.ISysUserService;
|
|
|
import com.usky.system.service.MceReceiveService;
|
|
|
import eu.bitwalker.useragentutils.UserAgent;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
-import java.util.Collections;
|
|
|
+import java.util.*;
|
|
|
|
|
|
import static com.usky.common.core.utils.ip.IpUtils.getIpAddr;
|
|
|
|
|
@@ -80,9 +81,11 @@ public class AsyncFactory
|
|
|
if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
|
|
|
logininfor.setStatus(String.valueOf(Constants.LOGIN_SUCCESS_STATUS)); // 使用String.valueOf进行转换
|
|
|
|
|
|
- // 如果登录成功,发送微信公众号消息
|
|
|
+ // 如果登录成功,发送微信公众号消息,删除超出规定历史token
|
|
|
if (Constants.LOGIN_SUCCESS.equals(status)) {
|
|
|
sendWeChatMessage(logininfor);
|
|
|
+ // 保留用户相同OS和Browser的最新两条token,删除其他所有token
|
|
|
+ retainLatestToken(username);
|
|
|
}
|
|
|
} else if (Constants.LOGIN_FAIL.equals(status)) {
|
|
|
logininfor.setStatus(String.valueOf(Constants.LOGIN_FAIL_STATUS)); // 使用String.valueOf进行转换
|
|
@@ -122,4 +125,67 @@ public class AsyncFactory
|
|
|
mceRequestVO.setIpAddress(logininfor.getIpaddr());
|
|
|
mceReceiveService.addMceReceive(mceRequestVO);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保留用户相同OS和Browser的最新两条token,删除其他历史token
|
|
|
+ *
|
|
|
+ * @param username 用户名
|
|
|
+ */
|
|
|
+ private static void retainLatestToken(String username) {
|
|
|
+ RedisService redisService = SpringContextUtils.getBean(RedisService.class);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 获取所有与该用户相关的token键
|
|
|
+ Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
|
|
|
+ if (keys == null || keys.isEmpty()) {
|
|
|
+ sys_user_logger.warn("Redis密钥为null或为空");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 存储该用户的token及其对应的LoginUser对象
|
|
|
+ Map<String, LoginUser> userTokens = new HashMap<>();
|
|
|
+
|
|
|
+ for (String key : keys) {
|
|
|
+ // 检查键是否存在并且未过期
|
|
|
+ if (redisService.hasKey(key)) {
|
|
|
+ LoginUser user = redisService.getCacheObject(key);
|
|
|
+ if (user != null && username.equals(user.getUsername())) {
|
|
|
+ userTokens.put(key, user);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (userTokens.isEmpty()) {
|
|
|
+ sys_user_logger.warn("未找到用户 {} 的任何token", username);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 找到最新的token
|
|
|
+ Map<String, List<LoginUser>> groupedTokens = new HashMap<>();
|
|
|
+ for (Map.Entry<String, LoginUser> entry : userTokens.entrySet()) {
|
|
|
+ String osBrowserKey = entry.getValue().getOs() + "-" + entry.getValue().getBrowser();
|
|
|
+ List<LoginUser> tokenList = groupedTokens.computeIfAbsent(osBrowserKey, k -> new ArrayList<>());
|
|
|
+ tokenList.add(entry.getValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ // OS和Browser组合,保留最新的两条token
|
|
|
+ List<String> tokensToDelete = new ArrayList<>();
|
|
|
+ for (List<LoginUser> tokenList : groupedTokens.values()) {
|
|
|
+ Collections.sort(tokenList, Comparator.comparing(LoginUser::getLoginTime).reversed());
|
|
|
+ for (int i = 2; i < tokenList.size(); i++) {
|
|
|
+ tokensToDelete.add(redisService.getCacheObject(tokenList.get(i).getToken()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 删除其他token
|
|
|
+ for (String tokenKey : tokensToDelete) {
|
|
|
+ boolean deleted = redisService.deleteObject(tokenKey);
|
|
|
+ System.out.println("Deleted Token Key: " + tokenKey + ", Result: " + deleted);
|
|
|
+ }
|
|
|
+
|
|
|
+ sys_user_logger.info("用户 {} 的token已清理,仅保留最新的两条token: {}", username, tokensToDelete.size());
|
|
|
+ } catch (Exception ex) {
|
|
|
+ sys_user_logger.error("清理用户 {} 的token时发生错误", username, ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|