思路:

巧用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);
    }

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐