系统登录的时候经常会有这种场景,如果密码连续N次输入错误,则要等N分钟之后才能重试。实现的方式有多种,比如在内存中维护一个数据结构来存储这些信息,但实现起来比较麻烦而且也存在问题,比如应用重启会导致数据丢失,并且内存的占用也是一个问题。
如果项目中已经有用到redis,那么使用redis来实现此功能是非常简单且有保障的。利用redis的String数据结构和超时自动过期机制,每错误一次,则错误值+1,并设置相应的过期时间,在登录的时候判断从key中获取到失败次数是否大于最大失败次数即可。
/**
* 登录次数错误+1
*
* @param userName
*/
private void increaseFailedLoginCounter(String userName) {
String key = ERROR_COUNT_KEY + userName;
JedisCluster cluster = jedisClusterManager.getJedisCluster();
String v = cluster.get(key);
if (org.springframework.util.StringUtils.isEmpty(v)) {
cluster.set(key, "1");
} else {
cluster.incr(key);
}
cluster.expire(key, 1800);
}