Kaynağa Gözat

fix 手机验证码错误封禁ip

zoujiajian 2 yıl önce
ebeveyn
işleme
14befc0087

+ 1 - 0
netflix-dao/src/main/java/com/cyksj/model/request/LoginReq.java

@@ -1,5 +1,6 @@
 package com.cyksj.model.request;
 
+import cn.hutool.http.server.HttpServerRequest;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;

+ 2 - 0
netflix-service/src/main/java/com/cyksj/redis/RedisService.java

@@ -611,6 +611,8 @@ public class RedisService {
         PHONE_CODE_KEY("phone_code_key:", "短信验证码", 60 * 3),
         PHONE_CODE_USER_NUM_KEY_DAY("phone_code_user_num_key:", "近一天获取验证码次数", 60 * 60 * 24l),
         PHONE_CODE_BALCK_KEY("phone_code_balck_key:", "手机黑名单", -1l),
+        PHONE_CODE_RETRY_TIME_KEY("phone_code_retry_time_key:", "手机登录重试key", 60 * 3),
+        BALCK_USER_IP_KEY("balck_user_ip_key:", "拉黑用户ip", 60 * 60 * 24),
         LOTTERY_KEY("lottery_key:%s", "抽奖key", 60 * 60 * 24l),
         TASK_TIME_LIMIT_KEY("task_time_limit:%s", "一次性任务key", 30),
         WX_GZH_QRCODE_LOGIN("wx_gzh_qrcode_login:%s", "微信公众号扫码登录key", 60),

+ 4 - 0
netflix-service/src/main/java/com/cyksj/service/user/BadIntentionOpService.java

@@ -1,5 +1,9 @@
 package com.cyksj.service.user;
 
+import javax.servlet.http.HttpServletRequest;
+
 public interface BadIntentionOpService {
     void checkHandleBadUserOp(String phone);
+
+    void isBadOpLoginPhone(HttpServletRequest request, String phone);
 }

+ 2 - 1
netflix-service/src/main/java/com/cyksj/service/user/UserService.java

@@ -8,6 +8,7 @@ import com.cyksj.model.entity.User;
 import com.cyksj.model.entity.WxSyncLog;
 import com.cyksj.model.request.LoginReq;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 
 /**
@@ -44,7 +45,7 @@ public interface UserService extends IService<User> {
 	/**
 	 * 验证码登录
 	 */
-	User webLogin(LoginReq loginReq) throws Exception;
+	User webLogin(LoginReq loginReq, HttpServletRequest request) throws Exception;
 
 	String bindWxAccountRedirect(String code, String state) throws Exception;
 

+ 28 - 0
netflix-service/src/main/java/com/cyksj/service/user/impl/BadIntentionOpServiceImpl.java

@@ -1,12 +1,16 @@
 package com.cyksj.service.user.impl;
 
+import cn.hutool.extra.servlet.ServletUtil;
 import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.StringUtil;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.user.BadIntentionOpService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import javax.servlet.http.HttpServletRequest;
+
 @Service
 @RequiredArgsConstructor
 @Slf4j
@@ -16,6 +20,8 @@ public class BadIntentionOpServiceImpl implements BadIntentionOpService {
     private static final int PHONE_CODE_GET_NUM_DAY_LIMIT = 30;
     private static final int PHONE_CODE_GET_NUM_DAY_MAX_BLACK = 50;
 
+    private static final int PHONE_LOGIN_CODE_RETRY = 10;
+
     @Override
     public void checkHandleBadUserOp(String phone) {
         if ("13662979985".equals(phone)) {
@@ -40,4 +46,26 @@ public class BadIntentionOpServiceImpl implements BadIntentionOpService {
         }
         redisService.set(dayKey, 1, RedisService.key.PHONE_CODE_USER_NUM_KEY_DAY.getTimeout());
     }
+
+    @Override
+    public void isBadOpLoginPhone(HttpServletRequest request, String phone) {
+        String ip = StringUtil.getInternalAddressByIP(ServletUtil.getClientIP(request));
+        String blackIpKey = RedisService.key.BALCK_USER_IP_KEY + ip;
+        if (redisService.hasKey(blackIpKey)) {
+            throw BusinessRuntimeException.getInstance("检测到您操作异常,请联系客服");
+        }
+        String RetryTimeKey = RedisService.key.PHONE_CODE_RETRY_TIME_KEY.getName() + phone;
+        if (redisService.hasKey(RetryTimeKey)) {
+            int i = Integer.parseInt(redisService.get(RetryTimeKey).toString());
+            if (i >= PHONE_LOGIN_CODE_RETRY) {
+                //锁住他的ip
+                redisService.setNx(blackIpKey, ip, RedisService.key.BALCK_USER_IP_KEY.getTimeout());
+                throw BusinessRuntimeException.getInstance("检测到您操作异常,请联系客服");
+            } else {
+                redisService.incr(RetryTimeKey, 1l);
+            }
+        } else {
+            redisService.setNx(RetryTimeKey, 1, RedisService.key.PHONE_CODE_RETRY_TIME_KEY.getTimeout());
+        }
+    }
 }

+ 7 - 4
netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java

@@ -36,6 +36,7 @@ import com.cyksj.service.mange.coupon.CouponCommonService;
 import com.cyksj.service.market.task.BindTaskService;
 import com.cyksj.service.shop.YhShopDistributeService;
 import com.cyksj.service.sys.SysConfigService;
+import com.cyksj.service.user.BadIntentionOpService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.service.user.UserLoginRecordService;
 import com.cyksj.service.user.UserService;
@@ -50,6 +51,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.Assert;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -117,8 +119,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 
 	private final UserDistributeSharedMapper userDistributeSharedMapper;
 
-	private final UserCertRecordMapper userCertRecordMapper;
-
+	private final BadIntentionOpService badIntentionOpService;
 	private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
 
 	@Override
@@ -370,7 +371,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 	}
 
 	@Override
-	public User webLogin(LoginReq loginReq) throws Exception {
+	public User webLogin(LoginReq loginReq, HttpServletRequest request) throws Exception {
 		LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class).last("limit 1");
 		if (loginReq.getType() == null || loginReq.getType() < 1 || loginReq.getType() > 3) {
 			throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新操作");
@@ -391,6 +392,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 				throw BusinessRuntimeException.getInstance("手机验证码已失效,请重新获取");
 			}
 			if (!StrUtil.equals(loginReq.getCode(), phoneCode.getCode())) {
+				//是否是恶意用户
+				badIntentionOpService.isBadOpLoginPhone(request, loginReq.getPhone());
 				throw BusinessRuntimeException.getInstance("手机验证码错误,请重新输入");
 			}
 			wrapper.eq(User::getLoginPhone, loginReq.getPhone());
@@ -409,7 +412,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 			redisService.del(RedisService.key.EMAIL_CODE_KEY.getNameFormat(loginReq.getEmail()));
 			wrapper.eq(User::getEmail, loginReq.getEmail());
 		}
-		if (loginReq.getType() == 3){
+		if (loginReq.getType() == 3) {
 			wrapper.eq(User::getEmail, loginReq.getEmail());
 		}
 		//保存用户信息

+ 2 - 2
netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java

@@ -442,7 +442,7 @@ public class AuthorizationController {
     @PostMapping("/login/phone")
     @NoSubmit
     public Result<UserAuthLoginResp> loginByPhone(@RequestBody LoginReq loginReq) throws Exception {
-        User user = userService.webLogin(loginReq);
+        User user = userService.webLogin(loginReq, request);
         Optional.ofNullable(user.getIsBlack())
                 .ifPresent(black -> {
                     if (black) {
@@ -517,7 +517,7 @@ public class AuthorizationController {
         loginReq.setType(3);
         loginReq.setEmail(googleLoginRep.getEmail());
         loginReq.setSubject(googleLoginRep.getSubject());
-        User user = userService.webLogin(loginReq);
+        User user = userService.webLogin(loginReq, request);
 
         Optional.ofNullable(user.getIsBlack())
                 .ifPresent(black -> {