java开发-登录提示:登录错误次数超过限制,请xxx分钟后重试,并限制登录,实现思路
前言
本文介绍了java开发中对于用户登录中,密码错误提示并限制登录做出分析和提供部分实现代码,通过Redis的StringRedisTemplate完成;
一、思路
首先分为两部分,第一部分是一登录就进行的查询部分,通过之后进入的判断部分;
- 1.查询部分
- 首先在用户登录的时候传入用户名和密码,将自定义的缓存Key跟用户名组合去查询redis,判断是否存在;
- 然后如果有这个key说明用户已经输入错误过密码,那么再去查询加锁key跟用户名组合去查询redis,判断是否加锁key的存在,如果存在直接返回给前端用户已被锁定;
- 2.判断部分
- 首先查询数据库,判断账户名或密码是否错误,
如果是密码错误才进入下面的判断;- 查询redis是否存在缓存验证key,如果不存在就创建,值为1,如果已经存在就加1并更新redis的Key值,并提示用户输入错误了几次,返回给前端;
- 如果输入错误大于规定的次数就锁定账户,创建一个加锁key,设置失效时间为12小时,并返回前端超过限制,锁定12小时后重试;
- 如果在没有锁定前密码已经输入正确就删除缓存验证key,因为上面已经加了判断,所以无需管加锁key
二、实现的代码
//用户缓存验证key
public static final String LOGIN_USER_KEY= "dq.login.verify.%s";
//用户加锁key
public static final String LOGIN_USER_LOCK_KEY= "dq.login.lock.%s";
//用户冻结时间(分)
public static final int LOGIN_USER_LOCK_TIME= 10;
//用户输入错误几次后提示用户
public static final int LOGIN_USER_LOCK_HINT_COUNT= 4;
//用户输入错误几次后提示用户剩余次数
public static final int LOGIN_USER_LOCK_LIFE_COUNT= 1;
//用户进入锁定的总次数
public static final int LOGIN_USER_LOCK_COUNT= 5;
/**
* 登录验证
*
* 账户锁定判定:输入指定的次数后锁定账户,删除判定的key,启用锁key,设置过期时间,等锁key过期就可以重新登录
*
* @param username
* 用户名
* @param password
* 密码
* @return 结果
*/
public Map login(String username, String password) {
//登录时先判断redis是否有用户的key
String loginFailKey = String.format(LOGIN_USER_KEY, username);
String loginValue = redisTemplate.opsForValue().get(loginFailKey);
if(StrUtil.isNotEmpty(loginFailKey )){
//用户加锁key
String loginLockKey = String.format(LOGIN_USER_LOCK_KEY, username);
String lockValue = redisTemplate.opsForValue().get(loginLockKey);
if(StrUtil.isNotEmpty(lockValue)){
// 超过限制次数
Long timeRest = redisTemplate.getExpire(loginLockKey, TimeUnit.MINUTES);
throw new LoginFailLimitException("登录错误次数超过限制,请" + timeRest + "分钟后 再试");
}
}
//xxx这里去写查询匹配账户名密码的代码
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//如果密码错误
if (如果密码错误的判断条件) {
//如果存在锁就提示
if(StrUtil.isNotEmpty(loginValue)){
int i = Integer.parseInt(loginValue);
//给用户提示
if(i==LOGIN_USER_LOCK_HINT_COUNT){
redisTemplate.opsForValue().set(loginFailKey,i+1+"",12,TimeUnit.HOURS);
throw new LoginFailLimitException("还剩"+LOGIN_USER_LOCK_LIFE_COUNT+"次机会,登录失败将锁定账户");
//锁定账户,重置用户登录失败次数
}else if(i==LOGIN_USER_LOCK_COUNT){
redisTemplate.opsForValue().set(loginLockKey, DateUtil.date().toString(),LOGIN_USER_LOCK_TIME,TimeUnit.MINUTES);
redisTemplate.delete(loginFailKey);
throw new LoginFailLimitException("登录错误次数超过限制,请" + LOGIN_USER_LOCK_TIME + "分钟后再试");
//登录失败次数加1
} else {
redisTemplate.opsForValue().set(loginFailKey,i+1+"",12,TimeUnit.HOURS);
}
}else {
redisTemplate.opsForValue().set(loginFailKey,"1",12,TimeUnit.HOURS);
}
//如果登录成功,清空失败次数
if(StrUtil.isNotEmpty(loginValue)){
redisTemplate.delete(loginFailKey);
}
}
仰天大笑出门去,我辈岂是蓬蒿人
版权声明:本文为weixin_48207312原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。