dzx 4 mesiacov pred
rodič
commit
9f5537df97

+ 6 - 0
src/main/java/com/xjrsoft/common/utils/LocalDateTimeUtil.java

@@ -12,6 +12,7 @@ import java.time.LocalTime;
 import java.time.Year;
 import java.time.YearMonth;
 import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
 
 public final class LocalDateTimeUtil {
     private LocalDateTimeUtil(){}
@@ -147,4 +148,9 @@ public final class LocalDateTimeUtil {
         // 检查目标日期是否在开始日期和结束日期之间(包含边界)
         return !targetDateTime.isBefore(startDateTime) && !targetDateTime.isAfter(endDateTime);
     }
+
+
+    public static long getMinutes(LocalDateTime startDateTime, LocalDateTime endDateTime){
+        return ChronoUnit.MINUTES.between(startDateTime, endDateTime);
+    }
 }

+ 39 - 0
src/main/java/com/xjrsoft/module/system/service/impl/LoginServiceImpl.java

@@ -13,11 +13,14 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
 import com.xjrsoft.common.constant.GlobalConstant;
 import com.xjrsoft.common.enums.EnabledMark;
 import com.xjrsoft.common.enums.RoleEnum;
 import com.xjrsoft.common.exception.MyException;
 import com.xjrsoft.common.utils.FixedArithmeticCaptcha;
+import com.xjrsoft.common.utils.LocalDateTimeUtil;
 import com.xjrsoft.common.utils.RSAUtil;
 import com.xjrsoft.common.utils.RedisUtil;
 import com.xjrsoft.common.utils.WeChatUtil;
@@ -36,6 +39,8 @@ import com.xjrsoft.module.system.vo.*;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
 import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
@@ -73,8 +78,18 @@ public class LoginServiceImpl implements ILoginService {
 
     private final IWhitelistManagementService whitelistManagementService;
 
+    private final static String loginErrorKey = "loginErrorCount";
+    private final static String loginLockKey = "loginLockTime";
+
     @Override
     public LoginVo login(LoginDto dto) throws Exception {
+        if(redisUtil.containsKey(dto.getUserName() + loginLockKey )){
+
+            LocalDateTime dateTime = redisUtil.get(dto.getUserName() + loginLockKey, LocalDateTime.class);
+            long minutes = ChronoUnit.MINUTES.between(LocalDateTime.now(), dateTime);
+
+            throw new MyException("账户被锁定!请在" + minutes + "分钟后重新登录");
+        }
         if (licenseConfig.getEnabled()) {
             //查出所有在线用户
             List<String> onlineUser = StpUtil.searchSessionId("", 0, -1, true);
@@ -104,7 +119,31 @@ public class LoginServiceImpl implements ILoginService {
                         .or()
                         .eq(User::getMobile, dto.getUserName()));
 
+
         if (loginUser == null || !BCrypt.checkpw(dto.getPassword(), loginUser.getPassword())) {
+            if(loginUser != null){
+                JsonObject loginErrorJson;
+                if(!redisUtil.containsKey(loginErrorKey)){
+                    //第一次登录失败
+                    loginErrorJson = new JsonObject();
+                    loginErrorJson.addProperty(loginUser.getId().toString(), 1);
+                }else{
+                    loginErrorJson = redisUtil.get(loginErrorKey, JsonObject.class);
+                    int count = loginErrorJson.get(loginUser.getId().toString()).getAsInt();
+                    if(count == 3){
+                        //密码错误3次,锁定登录
+                        LocalDateTime now = LocalDateTime.now();
+                        now.plusMinutes(10);
+                        redisUtil.set(loginUser.getUserName() + loginLockKey, now, 600);
+                        //锁定之后,清空次数计算
+                        loginErrorJson.remove(loginUser.getId().toString());
+                        redisUtil.set(loginErrorKey, loginErrorJson);
+                    }else{
+                        loginErrorJson.addProperty(loginUser.getId().toString(), count + 1);
+                        redisUtil.set(loginErrorKey, loginErrorJson);
+                    }
+                }
+            }
             throw new MyException("账号或密码不正确");
         }