思路:
巧用redis缓存计时,首先要明白应该有两个缓存,第一个是账户是否锁定的缓存,第二个是记录账户登录错误次数的缓存,而第二个缓存的有效时间就是要求的三分钟内出错的五次,那就是三分钟。第一个缓存有效期那就是锁定账户的五分钟。那么我们也可以一个key值两用,因为这两个缓存条件是互斥的,没有同时的情况,就两种情况,一种是错误次数没达到5次,那么缓存时间就是三分钟,另一种就是错误次数达到5次,那么缓存有效期就是五分钟,锁定账户。
有了思路直接上代码:
//登录验证时,3分钟内连续输错5次密码,锁住帐号;帐号锁住时间为5分钟,5分钟后解封
String loginId = sysUser.getUsername();//传进来的登录名
Boolean exit = redisService.hasKey(loginId);//查看缓存是否存在
//登录进来,第一步判断账户是否锁定,
if (exit == true && ("lock".equals(redisService.get(loginId)))) {
//redisService.setEx(loginId,"1", 300);//手动解锁
//获取锁定时间
long t = unlockTime(loginId)+1;
result.error500("该帐号登录已锁定,请"+t+"分钟后再试!");
return result;
}else
//第二步判断是否错误次数达到五次,如果达到5次,那就锁定账户,锁定值为lock,锁定时间5分钟
if (exit == true && "5".equals(redisService.get(loginId))) {
//锁帐号
redisService.set(loginId, "lock");
//设置锁定5分钟过期时间(秒)
redisService.expire(loginId, 5 * 60);
//获取锁定时间
long t = unlockTime(loginId)+1;
result.error500("该帐号登录已锁定,请"+t+"分钟后再试!");
return result;
}else { //其他情况就是错误没有达到五次和账户没有锁定的情况
//这儿是判断密码如果不一致,那就是登录失败
if (!syspassword.equals(userpassword)) {
// 如果缓存存在这个值,那么就加1,记录次数
if (redisService.hasKey(loginId)) {
String num = (String)redisService.get(loginId);
int i = Integer.parseInt(num); i++;
redisService.set(loginId,String.valueOf(i));
} else { //如果缓存不存在,起始值是1,有效期3分钟,方法单位为秒
redisService.setEx(loginId,"1", 180);//五分钟内错误次数
}
result.setCode(CommonConstant.SC_PASSWORD_ERROR_530);
result.setMessage("用户名或密码错误,第 " + redisService.get(loginId) + " 次登录失败");
return result;
}
}
//其余情况就是登录正确的时候,登录成功,记得清除该缓存
redisService.del(loginId);
//获取账户锁定多少分钟的方法
public long unlockTime(String loginId) {
return redisTemplate.opsForValue().getOperations().getExpire(loginId, TimeUnit.MINUTES);
}