From 3e9e81913bd8bde5b2ccde2c95acc7c5d94b32ba Mon Sep 17 00:00:00 2001
From: hjl <1657978663@qq.com>
Date: 星期五, 24 五月 2024 14:38:58 +0800
Subject: [PATCH] feat: 登录校验规则

---
 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java |   53 ++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
index 38eed13..31fb6ac 100644
--- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
@@ -3,7 +3,7 @@
 import com.alibaba.fastjson2.JSONObject;
 import com.ruoyi.common.core.constant.CacheConstants;
 import com.ruoyi.common.core.constant.SecurityConstants;
-import com.ruoyi.common.core.exception.GlobalException;
+import com.ruoyi.common.core.exception.user.StudyLoginException;
 import com.ruoyi.common.core.utils.JwtUtils;
 import com.ruoyi.common.core.utils.ServletUtils;
 import com.ruoyi.common.core.utils.StringUtils;
@@ -39,6 +39,8 @@
     private final static long expireTime = CacheConstants.EXPIRATION;
 
     private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
+
+    private final static String ACCESS_TOKEN_STUDY = CacheConstants.LOGIN_TOKEN_KEY_STUDY;
 
     private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
 
@@ -143,7 +145,7 @@
     public LoginUserParent getLoginUserStudy() {
         LoginUserParent userStudy = getLoginUserStudy(ServletUtils.getRequest());
         if (null == userStudy) {
-            throw new GlobalException("登录失效,请重新登录!");
+            throw new StudyLoginException("登录失效,请重新登录!", 505);
         }
         return userStudy;
     }
@@ -214,14 +216,18 @@
      */
     public LoginUserParent getLoginUserStudy(String token) {
         LoginUserParent user = null;
-        try {
-            if (StringUtils.isNotEmpty(token)) {
-                String userkey = JwtUtils.getUserKeyStudy(token);
-                user = redisService.getCacheObject(getTokenKey(userkey));
-                return user;
+        if (StringUtils.isNotEmpty(token)) {
+            String userkey = JwtUtils.getUserKeyStudy(token);
+            user = redisService.getCacheObject(getTokenKeyStudy(userkey));
+            // 优先判断当前账号是否已在其他设备登录
+            if (!user.getIsCanLogin()) {
+                throw new StudyLoginException("当前登录账号在其他设备登录!", 505);
             }
-        } catch (Exception e) {
-            e.printStackTrace();
+            // 再次判断登录状态是否已过期
+            if (System.currentTimeMillis() > user.getExpireTime()) {
+                throw new StudyLoginException("登录信息已过期,请重新登录!", 504);
+            }
+            return user;
         }
         return user;
     }
@@ -252,6 +258,16 @@
         if (StringUtils.isNotEmpty(token)) {
             String userkey = JwtUtils.getUserKey1(token);
             redisService.deleteObject(getTokenKey(userkey));
+        }
+    }
+
+    /**
+     * 学习端删除用户缓存信息
+     */
+    public void delLoginUserStudy(String token) {
+        if (StringUtils.isNotEmpty(token)) {
+            String userkey = JwtUtils.getUserKeyStudy(token);
+            redisService.deleteObject(getTokenKeyStudy(userkey));
         }
     }
 
@@ -320,27 +336,34 @@
      * 学习端用户登录
      */
     public void refreshTokenStudy(LoginUserParent dto) {
-        // 获取所有 login_tokens: 前缀的登录缓存
-        Set redisCache = redisService.getKeysPrefix(ACCESS_TOKEN + "*");
+        // 获取所有 login_tokens_study: 前缀的登录缓存
+        Set redisCache = redisService.getKeysPrefix(ACCESS_TOKEN_STUDY);
         for (Object key : redisCache) {
             String strKey = String.valueOf(key);
             // 根据 login_tokens:加密token 获取用户登录信息
             Object redisCacheUserInfo = redisService.getCacheObject(strKey);
             LoginUserParent redisUserInfo = JSONObject.parseObject(JSONObject.toJSONString(redisCacheUserInfo), LoginUserParent.class);
-            // 单点逻辑
-            if (dto.getPhone().equals(redisUserInfo.getPhone())) {
-                redisService.deleteObject(strKey);
+            // 单点逻辑,如果当前用户已处于登录状态并再次登录,则清除该用户上一次登录token
+            if (dto.getUserid().equals(redisUserInfo.getUserid())) {
+                // 设置能否登录字段为 否,当该token登录时,isCanLogin为false表示账号被挤
+                redisUserInfo.setIsCanLogin(Boolean.FALSE);
+                redisService.setCacheObject(strKey, redisUserInfo);
             }
         }
         // 单点登录逻辑
         dto.setLoginTime(System.currentTimeMillis());
         dto.setExpireTime(dto.getLoginTime() + expireTime * MILLIS_MINUTE);
         // 根据uuid将loginUser缓存
-        String userKey = getTokenKey(dto.getToken());
+        String userKey = getTokenKeyStudy(dto.getToken());
         redisService.setCacheObject(userKey, dto, expireTime, TimeUnit.MINUTES);
     }
 
     private String getTokenKey(String token) {
         return ACCESS_TOKEN + token;
     }
+
+    private String getTokenKeyStudy(String token) {
+        return ACCESS_TOKEN_STUDY + token;
+    }
+
 }
\ No newline at end of file

--
Gitblit v1.7.1