Redis实现统计登录失败次数,限制登陆

利用Redis实现统计登录失败次数,限制登陆

登录失败需要统计失败次数,达到一定次数需要等待一段时间才能尝试再次登录。本文利用redis实现此功能


一、基础的登录功能

SystemController


    @PostMapping("/adminLogin")
    public Result adminLogin(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password,
                             @RequestParam(value = "imageCode") String imageCode,HttpServletRequest request){

        //判断是否为账号密码是否为空——也可以通过@Valid 设置不能为空
        if (StringUtils.isBlank(username)){
            Result.error("用户名不能为空");
        }else if (StringUtils.isBlank(password)){
            Result.error("密码不能为空");
        }

        String ip =HttpUtil.getIpAddr(request);

        if (StringUtils.isBlank(imageCode)){
            return Result.error("验证码不能为空");
        }

        if (!codeManager.verifycode(ip,imageCode)){
            return Result.error("验证码不正确");
        }



        //根据用户名找角色
        Admin admin = adminService.getOne(new LambdaQueryWrapper<Admin>().eq(Admin::getUsername,username));

        if (admin==null){
            Result.error("用户名或者密码错误");
        }else {
            passwordCheckManager.checkPassword(admin.getUsername(),password,admin.getPassword(),Admin_Role);
        }

        SysUser sysUser = new SysUser();
        sysUser.setId(admin.getId());
        sysUser.setUsername(admin.getUsername());
        sysUser.setRole(Admin_Role);

        LoginVo loginVo = tokenManager.getToken(sysUser);

        Map data = new HashMap<>();
        data.put("LoginVo",loginVo);

        return Result.ok("登录成功",data);
    }

基本的登录接口,根据username去利用mybatis去获取对应的用户信息

若获取到信息则调用passwordCheckManger中的checkPassword方法,

若没有获取到信息,则提示用户名密码错误(找不到对应的信息)

PasswordCheckManger

@Component
public class PasswordCheckManager {

    @Autowired
    private RedisTemplate redisTemplate;

    private static final int LOGIN_ERRO_MAX = 5;

    private static final String CHECK_VALID_CODE_NUM_PREFIX = "checkerpassworderror:";

    public void checkPassword(String username,String password,String enpassword,String role){

        String checkPrefix= CHECK_VALID_CODE_NUM_PREFIX+role+"_";

        int count = 0;

        if (redisTemplate.hasKey(checkPrefix+username)){
            count = Integer.valueOf(redisTemplate.opsForValue().get(checkPrefix+username).toString());
        }

        if (count > LOGIN_ERRO_MAX){
            throw new GuliException("密码输错5次,请30分钟后尝试");
        }
        //半小时后失效
        redisTemplate.opsForValue().set(checkPrefix+username,count,30, TimeUnit.MINUTES);
        //密码不正确
        if (StringUtils.isEmpty(password)||!password.equals(enpassword)){
            count++;
            //半小时后失效
            redisTemplate.opsForValue().set(checkPrefix+username,count,30,TimeUnit.MINUTES);
            throw new GuliException("账号密码不正确");
        }


    }

校验前,会查询redis中是否存在该用户名的key存在。

checkPassword方法根据接口接收到的用户名和密码与数据库搜索到的进行比较,如果正确则返回登录成功。如果失败,则会根据用户名设置一个key存进redis中,赋值value为1,设定过期时间为30分钟。

如果该key存在,则让value+1,达到一定次数时,返回密码输错n次,请30分钟后尝试

其中的key值的命名以及错误的次数可以在配置文件中设置,然后此处引用。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值