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

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

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