当用户登录验证码错误次数太多时,需要限制用户在10分钟之内不能再次登录。
限制方案:
1.通过Redis ZSet
key可以设置为用户名,value可以设置为UUID,score设置为当前时间戳
每次用户登录时,通过 rangeByScore 查询对应的限制时间范围内错误的的次数,如果次数超过阈值,则限制登录。
java
private void limitErrorCount(String mobile) {
long currentTimeMillis = System.currentTimeMillis();
if(redisTemplate.hasKey(LOGIN_VC_ERROR_COUNT_KEY + mobile)) {
Integer size = redisTemplate.opsForZSet().rangeByScore(LOGIN_VC_ERROR_COUNT_KEY + mobile, currentTimeMillis - 3 * 60 * 1000, currentTimeMillis).size();
if (size != null && size >= 4) {
redisTemplate.opsForValue().set(LOGIN_VC_ACCOUNT_LOCK_KEY + mobile, true, 10, TimeUnit.MINUTES);
throw new BusinessException("验证码输入错误,账号将被锁定10分钟!");
}
}
redisTemplate.opsForZSet().add(LOGIN_VC_ERROR_COUNT_KEY + mobile, UUID.randomUUID().toString(), currentTimeMillis);
redisTemplate.expire(LOGIN_VC_ERROR_COUNT_KEY + mobile, 4, TimeUnit.MINUTES);
}
java
private void checkAccountLock(String mobile) {
Boolean accountLock = (Boolean)redisTemplate.opsForValue().get(LOGIN_VC_ACCOUNT_LOCK_KEY + mobile);
if(accountLock != null && BooleanUtils.isTrue(accountLock)) {
Long expireTime = redisTemplate.opsForValue().getOperations().getExpire(LOGIN_VC_ACCOUNT_LOCK_KEY + mobile, TimeUnit.MINUTES);
throw new BusinessException("账号已被锁定,请在" + (expireTime == null ? 1 : expireTime) + "分钟后登录!");
}
}