package com.cyksj.service.user.impl; import cn.hutool.core.util.ObjectUtil; import cn.hutool.extra.servlet.ServletUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.util.SmsUtil; 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.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @Service @RequiredArgsConstructor @Slf4j public class BadIntentionOpServiceImpl implements BadIntentionOpService { @Value("${smsVerify.apikey}") String apiKey; @Value("${smsVerify.shoppingApikey}") String shoppingApikey; private final RedisService redisService; 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; private static final String VERIFY_URL = "https://captcha.luosimao.com/api/site_verify"; @Override public void checkHandleBadUserOp(String phone, String verifyCode, String ticket, String randStr, HttpServletRequest request) { if ("13662979985".equals(phone)) { throw BusinessRuntimeException.getInstance("异常手机号"); } // if (StringUtils.isBlank(verifyCode)) { // throw BusinessRuntimeException.getInstance("人机校验不通过"); // } else { // //银河官网 // JSONObject res = checkVerifyCode(apiKey, verifyCode); // if (!res.getStr("res").equals("success")) { // //小店域名 // res = checkVerifyCode(shoppingApikey, verifyCode); // if (!res.getStr("res").equals("success")) { // log.error("手机号:{}验证码校验不通过 res:{}", phone, res); // throw BusinessRuntimeException.getInstance("人机校验不通过"); // } // } // } if (ObjectUtil.hasEmpty(ticket, randStr)) { throw BusinessRuntimeException.getInstance("请先完成图形认证"); } else { //腾讯云图形验证 String ip = StringUtil.getInternalAddressByIP(ServletUtil.getClientIP(request)); SmsUtil.checkTencentCaptcha(ticket, ip, randStr); } String dayKey = RedisService.key.PHONE_CODE_USER_NUM_KEY_DAY.getName() + phone; if (redisService.hasKey(RedisService.key.PHONE_CODE_BALCK_KEY.getName() + phone)) { throw BusinessRuntimeException.getInstance("异常手机号"); } if (redisService.hasKey(dayKey)) { Long incr = redisService.incr(dayKey, 1l); if (incr.intValue() >= PHONE_CODE_GET_NUM_DAY_MAX_BLACK) { log.error("近一天内手机号:{}获取验证码超过50次,移入黑名单", phone); redisService.set(RedisService.key.PHONE_CODE_BALCK_KEY.getName() + phone, phone); } if (incr.intValue() > PHONE_CODE_GET_NUM_DAY_LIMIT) { log.error("手机号:{}频繁获取短信验证码", phone); throw BusinessRuntimeException.getInstance("请勿频繁获取短信验证码"); } return; } 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)); log.info("--------------校验ip 是否黑名单------- ip:{}", ip); 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()); } } public JSONObject checkVerifyCode(String apiKey, String verifyCode) { Map parmas = new HashMap<>(); parmas.put("api_key", apiKey); parmas.put("response", verifyCode); String post = HttpUtil.post(VERIFY_URL, parmas); JSONObject res = new JSONObject(post); return res; } }