Эх сурвалжийг харах

添加是否允许多终端登录功能

wukai 1 жил өмнө
parent
commit
bde6a85ea0

+ 17 - 1
doc-admin/src/main/resources/application.yml

@@ -1,6 +1,20 @@
-
 # 公共配置
 server:
+  servlet:
+    # 应用的访问路径
+    context-path: /
+    tomcat:
+      # tomcat的URI编码
+      uri-encoding: UTF-8
+      # 连接数满后的排队数,默认为100
+      accept-count: 1000
+      # tomcat超时时间
+      max-connections: 30000
+      threads:
+        # tomcat最大线程数,默认为200
+        max: 800
+        # Tomcat启动初始化的线程数,默认值10
+        min-spare: 100
 
 # Spring配置
 spring:
@@ -31,6 +45,8 @@ token:
   secret: jjt@DOC.2023
   # 令牌有效期(默认30分钟)
   expireTime: 30
+  # 是否允许账户多终端同时登录(true允许 false不允许)
+  soloLogin: false
 
 # MyBatis配置
 mybatis-plus:

+ 1 - 0
doc-biz/src/main/java/com/doc/biz/ws/ChatMessageListener.java

@@ -36,6 +36,7 @@ public class ChatMessageListener implements MessageListener {
         String value = valueSerializer.deserialize(message.getBody());
 
         if (StringUtils.isNotBlank(value)) {
+            System.err.println(value);
             log.info("监听集群websocket消息--- {}", value);
             //集群模式 推送消息
             ObjectMapper mapper = new ObjectMapper();

+ 4 - 0
doc-common/src/main/java/com/doc/common/constant/Constants.java

@@ -148,4 +148,8 @@ public class Constants {
      * 图片文件
      */
     public static final String IMAGE_EXTENSION = ".bmp.gif.jpg.jpeg.png";
+    /**
+     * 新增一个常量LOGIN_USERID_KEY公用
+     */
+    public static final String LOGIN_USERID_KEY = "login_userid:";
 }

+ 1 - 1
doc-framework/src/main/java/com/doc/framework/security/handle/LogoutSuccessHandlerImpl.java

@@ -41,7 +41,7 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler {
         if (StringUtils.isNotNull(loginUser)) {
             String userName = loginUser.getUsername();
             // 删除用户缓存记录
-            tokenService.delLoginUser(loginUser.getToken());
+            tokenService.delLoginUser(loginUser.getToken(), loginUser.getUserId());
             // 记录用户退出日志
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
         }

+ 14 - 0
doc-framework/src/main/java/com/doc/framework/web/service/SysLoginService.java

@@ -17,6 +17,7 @@ import com.doc.framework.manager.factory.AsyncFactory;
 import com.doc.framework.security.context.AuthenticationContextHolder;
 import com.doc.system.service.ISysConfigService;
 import com.doc.system.service.ISysUserService;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -47,6 +48,9 @@ public class SysLoginService {
     @Resource
     private ISysConfigService configService;
 
+    @Value("${token.soloLogin}")
+    private boolean soloLogin;
+
     /**
      * 登录验证
      *
@@ -82,6 +86,16 @@ public class SysLoginService {
         AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
         LoginUser loginUser = (LoginUser) authentication.getPrincipal();
         recordLoginInfo(loginUser.getUserId());
+        // 判断是否允许账户多终端同时登录
+        if (!soloLogin) {
+            // 如果用户不允许多终端同时登录,清除缓存信息
+            String userIdKey = Constants.LOGIN_USERID_KEY + loginUser.getUser().getUserId();
+            String userKey = redisCache.getCacheObject(userIdKey);
+            if (StringUtils.isNotEmpty(userKey)) {
+                redisCache.deleteObject(userIdKey);
+                redisCache.deleteObject(userKey);
+            }
+        }
         // 生成token
         return tokenService.createToken(loginUser);
     }

+ 39 - 3
doc-framework/src/main/java/com/doc/framework/web/service/TokenService.java

@@ -29,17 +29,28 @@ import java.util.concurrent.TimeUnit;
  */
 @Component
 public class TokenService {
-    // 令牌自定义标识
+    /**
+     * 令牌自定义标识
+     */
     @Value("${token.header}")
     private String header;
 
-    // 令牌秘钥
+    /**
+     * 令牌秘钥
+     */
     @Value("${token.secret}")
     private String secret;
 
-    // 令牌有效期(默认30分钟)
+    /**
+     * 令牌有效期(默认30分钟)
+     */
     @Value("${token.expireTime}")
     private int expireTime;
+    /**
+     * 是否允许账户多终端同时登录(true允许 false不允许)
+     */
+    @Value("${token.soloLogin}")
+    private boolean soloLogin;
 
     protected static final long MILLIS_SECOND = 1000;
 
@@ -92,6 +103,26 @@ public class TokenService {
     }
 
     /**
+     * 删除用户身份信息
+     */
+    public void delLoginUser(String token, Long userId) {
+        if (StringUtils.isNotEmpty(token)) {
+            String userKey = getTokenKey(token);
+            redisCache.deleteObject(userKey);
+        }
+        //在原有代码上添加下面的代码
+        if (!soloLogin && StringUtils.isNotNull(userId)) {
+            String userIdKey = getUserIdKey(userId);
+            redisCache.deleteObject(userIdKey);
+        }
+    }
+
+    private String getUserIdKey(Long userId) {
+        return Constants.LOGIN_USERID_KEY + userId;
+    }
+
+
+    /**
      * 创建令牌
      *
      * @param loginUser 用户信息
@@ -133,6 +164,11 @@ public class TokenService {
         // 根据uuid将loginUser缓存
         String userKey = getTokenKey(loginUser.getToken());
         redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
+        if (!soloLogin) {
+            // 缓存用户唯一标识,防止同一帐号,同时登录
+            String userIdKey = getUserIdKey(loginUser.getUser().getUserId());
+            redisCache.setCacheObject(userIdKey, userKey, expireTime, TimeUnit.MINUTES);
+        }
     }
 
     /**