java开发-登录提示:登录错误次数超过限制,并限制登录,请xxx分钟后重试,实现思路

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版权协议,转载请附上原文出处链接和本声明。