专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

用这个Java框架实现密码错误后的账号锁定,简直不要太轻松

ins518 2024-10-04 23:38:21 技术文章 12 ℃ 0 评论

前言

我们在很多系统登录时中看到连续输错次数达到3次或5次后,账号会被锁定一段时间,有的是3分钟,有的是5分钟,有的甚至是限制当天都不能重新尝试(比如银行、支付宝等),只有达到相应的时间限制后才能继续尝试,类似下图,那么这种效果是如何实现的呢?

需求分析

其实这种需求在我们实际开发中会经常遇到,这是常规登录的一种安全性加强措施,防止有人恶意对账号密码进行爆破,特别是一些重要系统或管理员账号等高级别权限的情况。

首先我们先分析登录认证流程,用户输入账号密码登录-后端判断-成功则继续请求-失败则返回前端要求重新登录,流程非常简单。

而要加上锁定账号限制,我们肯定优先在后端实现,主要流程有以下变化:

  1. 登录请求时先判断账号是否锁定;
  2. 密码错误时先判断是连续几次错误;
  3. 错误不超过5次则返回密码错误信息,超过5次后后台锁定账号,用户再次登录时,不管哪个终端不管密码是否正确都会提示锁定。

所以,新的登录认证流程就变成了下图:

解决思路

其实解决方案有很多种,比如在后端用户表中加上错误次数,是否锁定,锁定开始时间,锁定解决时间等,每次请求时进行数据库的读写,但是这样无疑增加了读写的请求量,操作起来也不便捷,今天给大家介绍一种简单实现方法,采用Sa-token认证框架,主要应用到的API其实只有4个,只要灵活应用就可以实现我们的需求。

//锁定账号,第一个参数是用户ID,第二个是锁定时间,单位是秒
StpUtil.disable(userId,time)
//判断账号是否锁定
StpUtil.isDisable(userId)
//会话中设置某个参数,在设置超时次数时会用到
session.set(key,value)
//获取会话中某个参数
session.get(key)

具体实现代码如下:

@RequestMapping("/login")
    public SaResult login(String usrname,String pass){
        SaSession session=StpUtil.getSessionByLoginId(usrname);
        int errorCount=session.getInt("errCount");
        String errorUsr=session.getString("usrname");
        //判断当前账号是否是上一个输入错误的账号
        if(!usrname.equals(errorUsr)){
            session.set("usrname",usrname);
            errorCount=0;
            session.set("errCount",0);
        }
        //如果密码正确,且未锁定,进行登录,这是密码设置123456,实际认证时会请求数据库
        if(!StpUtil.isDisable(usrname)&&"123456".equals(pass)){
            StpUtil.login(usrname);
            session.set("usrname",usrname);
            session.set("errCount",0);
            return SaResult.ok("登录成功!");
        } else
        //如果当前账号已锁定,或当前账号输入错误超过5次,提示锁定信息
        if(StpUtil.isDisable(usrname)||(usrname.equals(errorUsr)&&errorCount>=5)){
            //如果是第一次锁定,锁定300秒
            if(!StpUtil.isDisable(usrname))StpUtil.disable(usrname,5*60);
            //返回锁定剩余时长
            return SaResult.error(String.format("密码错误超过5次,账号已锁定,请%d秒钟后再试",StpUtil.getDisableTime(usrname) ));
        }
        //错误次数+1
        else {
            errorCount++;
            session.set("errCount",errorCount);
        }
        return SaResult.data(String.format("账号或密码错误,请重试,错误次数%d", errorCount));
    }

我这里为了更贴近实际开发,返回消息体采用了SaResult进行了封装,提示信息可根据实际需求进行修改。

系统运行效果

为了测试效果,我做了个简单的登录页面,包括账号,密码两个输入框,实际开发中采用已有登录页面即可。

密码输入错误时,提示已连续错误次数:

密码输入错误超过5次时,锁定账号,提示剩余时间:

达到时间后自动解除锁定,再输入正确密码,提示登录成功

可以看到,我们自己要写的代码其实并不多,也没有与后端数据库,如果是大用户量的情况下,还可以集成redis框架。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表