當用戶登錄驗證碼錯誤次數太多時,需要限制用戶在10分鐘之內不能再次登錄。
限制方案:
1.通過Redis ZSet
key可以設置為用戶名,value可以設置為UUID,score設置為當前時間戳
每次用戶登錄時,通過 rangeByScore 查詢對應的限制時間范圍內錯誤的的次數,如果次數超過閾值,則限制登錄。
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);}
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) + "分鐘后登錄!");}}