From a134d96e96436e3c6b9f5e8191b3a2f672a740e8 Mon Sep 17 00:00:00 2001
From: lty <1179749281@qq.com>
Date: Fri, 6 Jan 2023 08:52:32 +0800
Subject: [PATCH] 同一用户只能一处登录 注销改为通过key进行校验

---
 jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java         | 30 ++++++++++++++++++++++++++++++
 jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java | 50 +++++++++++++++++++++++++++++++++-----------------
 2 files changed, 63 insertions(+), 17 deletions(-)

diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java
index 16f97b2..fa7bcf8 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java
@@ -24,9 +24,11 @@ import org.jeecg.modules.system.entity.SysUser;
 import org.jeecg.modules.system.model.SysLoginModel;
 import org.jeecg.modules.system.service.*;
 import org.jeecg.modules.system.util.RandImageUtil;
+import org.jeecg.modules.system.vo.SysUserOnlineVO;
 import org.jeecg.utils.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
@@ -56,6 +58,8 @@ public class LoginController {
 	@Autowired
 	private ISysTenantService sysTenantService;
 	@Autowired
+	public RedisTemplate redisTemplate;
+	@Autowired
     private ISysDictService sysDictService;
 	@Resource
 	private BaseCommonService baseCommonService;
@@ -430,6 +434,32 @@ public class LoginController {
 				obj.put("tenantList", tenantList);
 			}
 		}
+
+		//删除相同用户名称对应的key
+		Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*");
+		List<SysUserOnlineVO> onlineList = new ArrayList<SysUserOnlineVO>();
+		for (String key : keys) {
+			String token = (String) redisUtil.get(key);
+			LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token));
+			if (loginUser != null) {
+				if(oConvertUtils.isNotEmpty(username) && loginUser.getUsername().contains(username)){
+					log.info(" 强制  "+sysUser.getRealname()+"退出成功! ");
+					//清空用户登录Token缓存
+					redisUtil.del(token);
+					redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token);
+					//清空用户登录Shiro权限缓存
+					redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
+					//清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username>
+					redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
+					//调用shiro的logout
+					SecurityUtils.getSubject().logout();
+					//
+					redisUtil.del(key);
+				}
+			}
+		}
+
+
 		// update-end--Author:sunjianlei Date:20210802 for:获取用户租户信息
 		// 生成token
 		String token = JwtUtil.sign(username, syspassword, warehouseCode);
diff --git a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java
index 576c9fd..3dcc179 100644
--- a/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java
+++ b/jeecg-boot-master/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java
@@ -61,7 +61,7 @@ public class SysUserOnlineController {
             String token = (String)redisUtil.get(key);
             if (StringUtils.isNotEmpty(token)) {
                 SysUserOnlineVO online = new SysUserOnlineVO();
-                online.setToken(token);
+                online.setToken(key);
                 //TODO 改成一次性查询
                 LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token));
                 if (loginUser != null) {
@@ -112,22 +112,38 @@ public class SysUserOnlineController {
         if(oConvertUtils.isEmpty(online.getToken())) {
             return Result.error("退出登录失败!");
         }
-        String username = JwtUtil.getUsername(online.getToken());
-        LoginUser sysUser = sysBaseAPI.getUserByName(username);
-        if(sysUser!=null) {
-            baseCommonService.addLog("强制: "+sysUser.getRealname()+"退出成功!", CommonConstant.LOG_TYPE_1, null,sysUser);
-            log.info(" 强制  "+sysUser.getRealname()+"退出成功! ");
-            //清空用户登录Token缓存
-            redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + online.getToken());
-            //清空用户登录Shiro权限缓存
-            redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
-            //清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username>
-            redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
-            //调用shiro的logout
-            SecurityUtils.getSubject().logout();
-            return Result.ok("退出登录成功!");
-        }else {
-            return Result.error("Token无效!");
+        Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*");
+        List<SysUserOnlineVO> onlineList = new ArrayList<SysUserOnlineVO>();
+        for (String key : keys) {
+            if (key.equals(online.getToken()))
+            {
+                String tokenValue = (String)redisUtil.get(online.getToken());
+                String username = JwtUtil.getUsername(tokenValue);
+                LoginUser sysUser = sysBaseAPI.getUserByName(username);
+                if(sysUser!=null) {
+                    //update-begin--Author:wangshuai  Date:20200714  for:登出日志没有记录人员
+                    baseCommonService.addLog("用户名: "+sysUser.getRealname()+",退出成功!", CommonConstant.LOG_TYPE_1, null,sysUser);
+                    //update-end--Author:wangshuai  Date:20200714  for:登出日志没有记录人员
+                    log.info(" 用户名:  "+sysUser.getRealname()+",退出成功! ");
+
+                    //以下两个清空测试无效 保留在这吧
+                    //清空用户登录Token缓存/用户登录Shiro权限缓存
+                    redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + tokenValue);
+                    redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
+
+                    //真*清空Token
+                    redisUtil.del(key);
+
+                    //清空用户的缓存信息
+                    redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
+                    //调用shiro的logout
+                    SecurityUtils.getSubject().logout();
+                    return Result.ok("退出登录成功!");
+                }else {
+                    return Result.error("Token无效!");
+                }
+            }
         }
+        return Result.error("Token无效!");
     }
 }
--
libgit2 0.22.2