springboot+redis实现登录失败次数限制
需求:为了防止枚举攻击,完成安全性测试扫描。先是保证账号和密码其一错误但返回错误一致,添加Referer拦截器,现在需要限制登录失败次数限制,本文做的是登录失败五次账号锁定3小时。登录Controller添加如下代码@Autowiredprivate RedisTemplate<String, String> redisTemplate;//用户登录是否被锁定三小时 redisKey
·
需求:为了防止枚举攻击,完成安全性测试扫描。先是保证账号和密码其一错误但返回错误一致,添加Referer拦截器,现在需要限制登录失败次数限制,本文做的是累计登录失败五次账号锁定3小时。(如果有一次登录成功则会重新计数)
登录Controller添加如下代码
@Autowired
private RedisTemplate<String, String> redisTemplate;
//用户登录是否被锁定 三小时 redisKey 前缀
private String SHIRO_IS_LOCK = "shiro-is-lock:";
// 以下放在方法内
ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
// 判断该用户是否被锁
if ("LOCK".equals(opsForValue.get(SHIRO_IS_LOCK + person.getUsername()))) {
return ResponseVo.fail("登录失败次数过多已锁定,请稍后再试");
}
在service实现类里登录失败后按业务增加如下代码
@Autowired
private RedisTemplate<String, String> redisTemplate;
//用户登录次数计数 redisKey 前缀
private String SHIRO_LOGIN_COUNT = "shiro-login-count:";
//用户登录是否被锁定 一小时 redisKey 前缀
private String SHIRO_IS_LOCK = "shiro-is-lock:";
ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
//条件根据实际
if (result.containsKey("errcode") || result.containsKey("errmsg")) {
opsForValue.increment(SHIRO_LOGIN_COUNT + username, 1);
//计数大于5时,设置用户被锁定三小时
if (Integer.parseInt(opsForValue.get(SHIRO_LOGIN_COUNT + username)) >= 5) {
opsForValue.set(SHIRO_IS_LOCK + username, "LOCK", 3, TimeUnit.HOURS);
redisTemplate.expire(SHIRO_LOGIN_COUNT + username,3,TimeUnit.HOURS);
return ResponseVo.fail("登录失败次数过多已锁定,请稍后再试");
}
return ResponseVo.fail("登录失败" + opsForValue.get(SHIRO_LOGIN_COUNT + username) + "次,请检查用户名或密码");
}
opsForValue.set(SHIRO_LOGIN_COUNT + username, "0");
opsForValue.set(SHIRO_IS_LOCK + username, "UNLOCK");
仅本文仅记录个大概实现 具体锁定多久 返回错误码描述 是否需要提示锁定剩余多长时间 根据业务需求而定。
其实也有了解 可以在数据库做几个字段 账号状态 上次登录失败时间等 来做这个需求 但是个人觉得使用redis更加简洁~~
更多推荐
已为社区贡献1条内容
所有评论(0)