Commit d0b9daac authored by 技术部-任文超's avatar 技术部-任文超

账密登录验证码添加计数开关,账密错误3次后才要求用户输入图形验证码

parent 502c3c50
......@@ -13,6 +13,7 @@ public interface Constants {
String IMAGE_CAPTCHA_KEY = "img_captcha:";
String ONE_TIME_TOKEN = "oneTimeToken";
String REDIS_PASSWORD_ERROR_COUNT = "password_error_4_phone:";
String REDIS_CAPTCHA_KEY = "auth:";
String REDIS_CAPTCHA_KEY_PATTERN = REDIS_CAPTCHA_KEY + IMAGE_CAPTCHA_KEY + "*";
......
......@@ -39,7 +39,6 @@ public class CaptchaFiniteValidateAdvisor {
private static final Logger LOGGER = LoggerFactory.getLogger(CaptchaFiniteValidateAdvisor.class);
private static final String SUPER_CAPTCHA_ID = UUID.nameUUIDFromBytes("__QG_APPCLIENT_AGENT__".getBytes(Charset.forName("UTF-8"))).toString();
private static final String SUPER_CAPTCHA = "__SUPERQG__";
private static final String IMAGE_CAPTCHA_ID_COUNT = "image:captcha_id:count:";
/**
* 图形验证码错误计数器生命周期,与图形验证码生命周期保持一致
* 参照点:cn.quantgroup.xyqb.config.captcha.RedisCaptchaStore{
......@@ -83,7 +82,10 @@ public class CaptchaFiniteValidateAdvisor {
String registerFrom = Optional.ofNullable(request.getParameter("registerFrom")).orElse("");
String captchaId = Optional.ofNullable(request.getParameter("captchaId")).orElse("");
Object captchaValue = request.getParameter("captchaValue");
String phoneNo = request.getParameter("phoneNo");
String deviceId = Optional.ofNullable(request.getParameter("deviceId")).orElse("");
Long countErrorByPhone = getCount(phoneNo);
if (countErrorByPhone > Constants.Image_Need_Count) {
if (shouldSkipCaptchaValidate(registerFrom, captchaId, captchaValue)) {
LOGGER.info("使用超级图形验证码校验, registerFrom={}, clientIp={}", registerFrom, request.getRemoteAddr());
return pjp.proceed();
......@@ -94,10 +96,6 @@ public class CaptchaFiniteValidateAdvisor {
captcha = StringUtils.lowerCase(captcha);
// 验证码校验
Boolean validCaptcha = false;
Long captchaCount = countCaptchaId(captchaId);
if(captchaCount == null || captchaCount >= Constants.IMAGE_FINITE_COUNT){
return JsonResult.buildSuccessResult("验证码失效,请重新获取", "", 2L);
}
try {
validCaptcha = imageCaptchaService.validateResponseForID(Constants.IMAGE_CAPTCHA_KEY + captchaId, captcha);
} catch (CaptchaServiceException ex) {
......@@ -109,6 +107,8 @@ public class CaptchaFiniteValidateAdvisor {
}
return JsonResult.buildSuccessResult("图形验证码不正确", "", 2L);
}
return pjp.proceed();
}
private boolean shouldSkipCaptchaValidate(String registerFrom, String captchaId, Object captchaValue) {
// 如果启用了超级验证码功能, 检查超级验证码, 超级验证码区分大小写
......@@ -118,22 +118,21 @@ public class CaptchaFiniteValidateAdvisor {
return StringUtils.equals(SUPER_CAPTCHA_ID, String.valueOf(captchaId)) && StringUtils.equals(SUPER_CAPTCHA, String.valueOf(captchaValue));
}
private Long countCaptchaId(String captchaId) {
String captchaKey = getKey(captchaId);
if(StringUtils.isBlank(captchaKey)){
return null;
}
if (!redisTemplate.hasKey(captchaKey)) {
redisTemplate.opsForValue().set(captchaKey, String.valueOf(0), SECONDS, TimeUnit.SECONDS);
// 获取该账号密码错误计数器
private Long getCount(String phoneNo) {
String key = getKey(phoneNo);
String countString = redisTemplate.opsForValue().get(key);
if (StringUtils.isBlank(countString)) {
return 0L;
}
return redisTemplate.opsForValue().increment(captchaKey, 1L);
return Long.valueOf(countString);
}
private final static String getKey(String captchaId){
if(StringUtils.isBlank(captchaId)){
private final static String getKey(String phoneNo){
if(StringUtils.isBlank(phoneNo)){
return null;
}
return IMAGE_CAPTCHA_ID_COUNT + captchaId;
return Constants.REDIS_PASSWORD_ERROR_COUNT + phoneNo;
}
}
......@@ -41,6 +41,7 @@ import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* Http服务接口:用户注册、登录、重置密码
......@@ -94,9 +95,9 @@ public class UserController implements IBaseController {
* @param dimension
* @return
*/
@CaptchaValidator
@RequestMapping("/loginForH5")
@CaptchaFineteValidator
@LogHttpCaller
@RequestMapping("/loginForH5")
public JsonResult loginWithFineteCaptcha(
@RequestParam(required = false, defaultValue = "1") Long channelId, String appChannel,
@RequestParam(required = false, defaultValue = "1") Long createdFrom,
......@@ -122,8 +123,8 @@ public class UserController implements IBaseController {
* @return
*/
@OneTimeTokenValidator
@RequestMapping("/login/fastForH5")
@LogHttpCaller
@RequestMapping("/login/fastForH5")
public JsonResult loginFastWithFineteCaptcha(
@RequestParam(required = false, defaultValue = "1") Long channelId, String appChannel,
@RequestParam(required = false, defaultValue = "1") Long createdFrom,
......@@ -133,8 +134,8 @@ public class UserController implements IBaseController {
return loginFast(channelId, appChannel, createdFrom, key, btRegisterChannelId, dimension, request);
}
@RequestMapping("/login")
@LogHttpCaller
@RequestMapping("/login")
public JsonResult login(
@RequestParam(required = false, defaultValue = "1") Long channelId, String appChannel,
@RequestParam(required = false, defaultValue = "1") Long createdFrom,
......@@ -290,8 +291,8 @@ public class UserController implements IBaseController {
* @param channelId
* @return
*/
@RequestMapping("/register/fast")
@LogHttpCaller
@RequestMapping("/register/fast")
public JsonResult registerFast(@RequestParam String phoneNo, @RequestParam String verificationCode, @RequestParam(required = false) Long channelId,
@RequestParam(required = false) Long registerFrom, @RequestParam(required = false, defaultValue = "") String appChannel,
@RequestParam(required = false)Long btRegisterChannelId,@RequestParam(required = false)String dimension) {
......@@ -339,7 +340,6 @@ public class UserController implements IBaseController {
*/
@LogHttpCaller
@RequestMapping("/register")
@LogHttpCaller
public JsonResult register(@RequestParam String phoneNo, @RequestParam String password,
@RequestParam String verificationCode, @RequestParam(required = false) Long channelId,
@RequestParam(required = false) Long registerFrom,
......@@ -411,8 +411,8 @@ public class UserController implements IBaseController {
* @param verificationCode
* @return
*/
@RequestMapping("/reset_password")
@LogHttpCaller
@RequestMapping("/reset_password")
public JsonResult resetPassword(@RequestParam String phoneNo,
@RequestParam String password,
@RequestParam(required = false) String registerFrom,
......@@ -551,6 +551,13 @@ public class UserController implements IBaseController {
}
//验证密码
if (!validatePassword(pass, user.getPassword())) {
// 密码错误时,给该账号添加计数器
String key = Constants.REDIS_PASSWORD_ERROR_COUNT + userName;
if (!stringRedisTemplate.hasKey(key)) {
stringRedisTemplate.opsForValue().set(key, String.valueOf(0), Constants.ONE_DAY, TimeUnit.SECONDS);
}
// 密码错误计数
stringRedisTemplate.opsForValue().increment(key, 1L);
return null;
}
return user;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment