Browse Source

feat:两江消防车辆联网系统登录验证码对接

TwoKe945 1 year ago
parent
commit
371c9f3800

+ 0 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java

@@ -3,7 +3,6 @@ package com.ruoyi.web.controller.system;
 import java.util.List;
 import java.util.Set;
 
-import com.ruoyi.framework.web.service.SysPasswordService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;

+ 1 - 1
ruoyi-admin/src/main/resources/application.yml

@@ -45,7 +45,7 @@ user:
     # 密码最大错误次数
     maxRetryCount: 3
     # 密码锁定时间(默认10分钟)
-    lockTime: 0
+    lockTime: 10
 
 # Spring配置
 spring:

+ 23 - 0
ruoyi-common/src/main/java/com/ruoyi/common/exception/user/PasswordRetryLimitExceedException.java

@@ -0,0 +1,23 @@
+package com.ruoyi.common.exception.user;
+
+public class PasswordRetryLimitExceedException extends RuntimeException {
+
+    private Boolean needCode = false;
+
+    public PasswordRetryLimitExceedException() {
+        this.needCode = false;
+    }
+
+    public PasswordRetryLimitExceedException(String message, Boolean needCode) {
+        super(message);
+        this.needCode = needCode;
+    }
+
+    public Boolean getNeedCode() {
+        return needCode;
+    }
+
+    public void setNeedCode(Boolean needCode) {
+        this.needCode = needCode;
+    }
+}

+ 15 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java

@@ -1,6 +1,8 @@
 package com.ruoyi.framework.web.exception;
 
 import javax.servlet.http.HttpServletRequest;
+
+import com.ruoyi.common.exception.user.PasswordRetryLimitExceedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.access.AccessDeniedException;
@@ -59,6 +61,19 @@ public class GlobalExceptionHandler
         return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
     }
 
+    /**
+     * 需要填写验证码的运行时异常
+     */
+    @ExceptionHandler(PasswordRetryLimitExceedException.class)
+    public AjaxResult handleRuntimeException(PasswordRetryLimitExceedException e, HttpServletRequest request)
+    {
+        String requestURI = request.getRequestURI();
+        log.error("请求地址'{}',需要填写验证码.", requestURI, e);
+        AjaxResult error = AjaxResult.error(e.getMessage());
+        error.put("needCaptchaCode", true);
+        return error;
+    }
+
     /**
      * 拦截未知的运行时异常
      */

+ 13 - 7
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java

@@ -1,6 +1,8 @@
 package com.ruoyi.framework.web.service;
 
 import javax.annotation.Resource;
+
+import com.ruoyi.common.exception.user.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.BadCredentialsException;
@@ -14,11 +16,6 @@ import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.exception.ServiceException;
-import com.ruoyi.common.exception.user.BlackListException;
-import com.ruoyi.common.exception.user.CaptchaException;
-import com.ruoyi.common.exception.user.CaptchaExpireException;
-import com.ruoyi.common.exception.user.UserNotExistsException;
-import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.MessageUtils;
 import com.ruoyi.common.utils.StringUtils;
@@ -29,6 +26,8 @@ import com.ruoyi.framework.security.context.AuthenticationContextHolder;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysUserService;
 
+import java.util.Objects;
+
 /**
  * 登录校验方法
  * 
@@ -66,8 +65,12 @@ public class SysLoginService
     public String login(String username, String password, String code, String uuid)
     {
         if (sysPasswordService.needCode(username)) {
-            // 验证码校验
-            validateCaptcha(username, code, uuid);
+            if (Objects.isNull(code)) {
+                throw new PasswordRetryLimitExceedException("请输入验证码", true);
+            } else {
+                // 验证码校验
+                validateCaptcha(username, code, uuid);
+            }
         }
         // 登录前置校验
         loginPreCheck(username, password);
@@ -87,6 +90,9 @@ public class SysLoginService
                 AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                 throw new UserPasswordNotMatchException();
             }
+            else if(SysPasswordService.NEED_VERIFICATION_CODE.equals(e.getMessage())) {
+                throw new PasswordRetryLimitExceedException(sysPasswordService.retryMessage(username), true);
+            }
             else
             {
                 AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));

+ 17 - 6
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysPasswordService.java

@@ -1,8 +1,5 @@
 package com.ruoyi.framework.web.service;
 
-import java.util.concurrent.TimeUnit;
-
-import com.ruoyi.common.exception.user.UserException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.core.Authentication;
@@ -12,13 +9,14 @@ import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
-import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException;
 import com.ruoyi.common.utils.MessageUtils;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.framework.manager.AsyncManager;
 import com.ruoyi.framework.manager.factory.AsyncFactory;
 import com.ruoyi.framework.security.context.AuthenticationContextHolder;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * 登录密码方法
  * 
@@ -38,7 +36,7 @@ public class SysPasswordService
 
     /**
      * 登录账户密码错误次数缓存键名
-     * 
+     *
      * @param username 用户名
      * @return 缓存键key
      */
@@ -56,6 +54,14 @@ public class SysPasswordService
         return retryCount >= Integer.valueOf(maxRetryCount).intValue();
     }
 
+    public String retryMessage(String username) {
+        Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
+        return  MessageUtils.message("user.password.retry.limit.count", retryCount);
+    }
+
+
+    public static String NEED_VERIFICATION_CODE = "NEED_VERIFICATION_CODE";
+
     public void validate(SysUser user)
     {
         Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
@@ -82,7 +88,10 @@ public class SysPasswordService
             retryCount = retryCount + 1;
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
                     MessageUtils.message("user.password.retry.limit.count", retryCount)));
-             redisCache.setCacheObject(getCacheKey(username), retryCount);
+             redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
+             if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) {
+                 throw new RuntimeException(NEED_VERIFICATION_CODE);
+             }
             throw new UserPasswordNotMatchException();
         }
         else
@@ -91,6 +100,8 @@ public class SysPasswordService
         }
     }
 
+
+
     public boolean matches(SysUser user, String rawPassword)
     {
         return SecurityUtils.matchesPassword(rawPassword, user.getPassword());