用Redis实现限制登录功能案例

限制登录功能

需求描述:

用户在2分钟内,仅允许输入错误密码5次。
如果超过次数,限制其登录1小时。(要求每登录失败时,都要给相应提式)

service层

@Service
public class LoginServiceImpl implements LoginService {
     

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    @Override
    public int login(String username, String password) {
     

        //判断用户名是否存在
        if(!redisTemplate.hasKey(username)){
     
            return 3800;
        }

        //判断当前用户是否被限制,若被限制,返回剩余限制时间
        if(redisTemplate.hasKey("username"+username)){
     
            long time = redisTemplate.opsForValue().getOperations().getExpire("username" + username);
            return (int) time;
        }

        //根据用户名获取密码
        String pwd = redisTemplate.opsForValue().get(username);
        //判断数据库中是否有登录次数标记,如果没有说明当前用户还没有登录过,将次数设置为5次,时间设置为2分钟
        if(!redisTemplate.hasKey("count"+username)){
     
            redisTemplate.opsForValue().set("count"+username,"3675");
            redisTemplate.opsForValue().set("counttime"+username,"",2,TimeUnit.MINUTES);
        }

        //判断当前用户2分钟内是否已经输了五次密码,没有输到五次,则重置2分钟内可登录5次
        if(!redisTemplate.hasKey("counttime"+username)){
     
            redisTemplate.opsForValue().set("count"+username,"3675");
            redisTemplate.opsForValue().set("counttime"+username,"",2,TimeUnit.MINUTES);
        }

        //如果密码一致,就删除次数的记录和2分钟的时间记录
        if(password.equals(pwd)){
     
            redisTemplate.delete("count"+username);
            redisTemplate.delete("counttime"+username);
            return 3665;
        }else{
     
            //如果密码不一致,计数器减一
            redisTemplate.opsForValue().decrement("count"+username);
            String count = redisTemplate.opsForValue().get("count"+username);
            //如果输入五次不正确,添加当前用户被限制登录1小时的倒计时,并且删除次数标记和2分钟时间标记
            if(count.equals("3670")){
     
                redisTemplate.delete("count"+username);
                redisTemplate.delete("counttime"+username);
                redisTemplate.opsForValue().set("username"+username,"",60,TimeUnit.MINUTES);
            }
            return Integer.parseInt(count);

        }
    }
}

controller层

@Controller
public class LoginController {
     

    @Autowired
    private LoginService loginService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @RequestMapping("login")
    public String login(){
     
        return "login";
    }


    @ResponseBody
    @RequestMapping("checkLogin")
    public int checkLogin(String username, String password){
     
        int i = loginService.login(username, password);
        return i;
    }

}

前端ajax

<script type="text/javascript">
  function binding(){
     

    var username = $.trim($('#username').val());
    var password = $.trim($('#password').val());
    $.ajax({
     
      type:"post",
      url:"/checkLogin",
      data:{
     "username":username,"password":password},
      success:function (i) {
     
        if(i==3665){
     
          alert("登录成功")
        }else if(i>=3670&&i<3675){
     
          if(i==3670){
     
            alert("您已经五次登录失败,一小时内不允许登录")
          }else{
     
            alert("登录失败,您还有"+(i-3670)+"次机会")
          }
        }else if(i==3800){
     
          alert("对不起,用户名不存在")
        }else{
     
          alert("您还有"+i+"秒时间限制")
        }
      }
    })
  }

</script>

至于返回值建议返回String,返回int不太好

你可能感兴趣的:(redis)