1. 在登录入口就进行判断,判断redis 中是否存在用户名的次数
String accountName = securityAccount.getAccountName();
String frequencys = "frequency";
String accountNameFrequency=accountName+frequencys;
//获取redis中用户名称次数
Object osrt = redisTemplate.opsForValue().get(accountNameFrequency);
if(Base.isNotNull(osrt)) {
int parseInt = Integer.parseInt(osrt.toString());
if (Base.isNotNull(parseInt) && parseInt >= 15) {
//连续登录失败15次,请明天再来试试吧!
throw new BusinessException(ExceptionCode.EXCEPTION_CODE0050);
}
}
//限制连续登录失败5次,锁定时间内不进行计数
Object accountNames = redisTemplate.opsForValue().get(securityAccount.getAccountName());
if(Base.isNotNull(accountNames)) {
int parseInt = Integer.parseInt(accountNames.toString());
if (Base.isNotNull(parseInt) && parseInt == 5) {
throw new BusinessException(ExceptionCode.EXCEPTION_CODE0049);
}
}
2. 用户登录失败以后,进行已用户名作为key, 次数是value 进行计数。存两个次数 1个次数清空,一个次数一直累加到15次
//验证登录失败写入redis,使用increment进行计数自增
redisTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
//第三次连续登录失败累计15次,请明天再来试试吧!
int intValue = redisTemplate.opsForValue().increment(securityAccount.getAccountName()).intValue();
int value = redisTemplate.opsForValue().increment(accountNameFrequency).intValue();
if(value >=15){
redisTemplate.expire(securityAccount.getAccountName(), 720, TimeUnit.MINUTES);
throw new BusinessException(ExceptionCode.EXCEPTION_CODE0050);
}
if(value ==5){
redisTemplate.expire(securityAccount.getAccountName(),30 , TimeUnit.MINUTES);
throw new BusinessException(ExceptionCode.EXCEPTION_CODE0049);
}
//第二次登录连续5次失败,请30分钟后再试! 剩余等待时间: 30分钟
if(value ==10){
redisTemplate.expire(securityAccount.getAccountName(), 30, TimeUnit.MINUTES);
throw new BusinessException(ExceptionCode.EXCEPTION_CODE0049);
}
throw new BusinessException(ExceptionCode.EXCEPTION_CODE0048);
3. //登录连续5次失败,即使输入正确的用户名密码也需要时间到了才可以登录
Object frequency = redisTemplate.opsForValue().get(securityAccount.getAccountName());
if(Base.isNotNull(frequency)) {
int parseInt = Integer.parseInt(frequency.toString());
if (Base.isNotNull(parseInt) && parseInt == 5) {
//登录连续5次失败,请30分钟后再试! 剩余等待时间: 30分钟
throw new BusinessException(ExceptionCode.EXCEPTION_CODE0049);
}
if (Base.isNotNull(parseInt) && parseInt == 10) {
//登录连续5次失败,请30分钟后再试! 剩余等待时间: 30分钟
throw new BusinessException(ExceptionCode.EXCEPTION_CODE0049);
}
}
//登录成功,清除redis 次数和用户名
redisTemplate.delete(accountNameFrequency);
redisTemplate.delete(securityAccount.getAccountName());
/** * description 计算登陆15次错误以后过期时间 * @author wangbeibei 2021/12/8 */ private int expirationTime()throws Exception { //过期时间为当前23:59:59秒 String expirationTime = getCurrentDate(0,YYYY_MM_DD+" 23:59:59"); //获取当前时间 String currentTime = Base.getCurrentDate(0, YYYY_MM_DD_HH_MM_SS); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date expirationTimes = sdf.parse(expirationTime); Date currentTimes = sdf.parse(currentTime); //过期时间减去当前时间 long expirationTim = expirationTimes.getTime() - currentTimes.getTime(); long time = expirationTim / 1000; int expiration= new Long(time).intValue(); return expiration; }