java登录程序用户密码5分钟内输错3次锁定用户账号一天的实现

最近在公司实习的项目遇到这么一个业务需求:用户登录时如果5分钟内密码连续3次输入错误就将用户锁定,24小时后自动解锁。
分析一下,这个需求有很多种方法可以实现,比较简单的就是采用数据库来实现,我采用的是比较老实的办法,欢迎大家留言指正。
公司开发采用的是struts1.1+Oracle+MVC,由于某些样式不支持的问题,用户登录数据的检验这些操作我都是传输到servlet中进行的。

第一步:建用户登录记录表

直接贴出sql语句:

create table C_LOGIN_RECORD
(
  c_id        NUMBER(10) not null, --登录记录ID,不为空
  username    VARCHAR2(40),       --用户名
  lock_flag   VARCHAR2(10),       --锁定标志,'1'代表锁定状态 '0'未锁定状态
  failure_num VARCHAR2(10),       --登录失败次数
  login_date  DATE                --登录时间,默认为当前时间
)
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

登录的时候直接往其中插入数据就好,这里c_id字段非空,是自动递增的,由于在oracle中没有自带的acto-increment,所以采用触发器+序列的方式来实现,代码如下:

-- Create sequence 
create sequence LOGIN_AUTOINC_SEQ
minvalue 1
maxvalue 99999999
start with 43
increment by 1
nocache
order;
-- Create trigger 
create or replace trigger login_autoinc_tg
  before insert on C_LOGIN_RECORD
  for each row
begin
  select login_autoinc_seq.nextval into :new.c_id from dual;
end login_autoinc_tg;
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

当往其中插入数据的时候,就会触发触发器,获得ID


第二步:完成dao层的方法

UserParaDao.java
/**
     * 判断用户名和密码是否匹配
     * 
     * @param userPara
     * @return
     * @throws Exception
     */
    public boolean checkNameAndPsw(UserPara userPara) throws Exception {
        String sql = "SELECT PASSWORD FROM C_USER WHERE NAME=?\n";
        ResultSet rs = DaoUtil.executeQuery(DaoTools.getConnName(), sql,
                new String[] { userPara.getName() });/*说明一下,这里和后面用到的DaoUtil.executeQuery()方法是公司平台封装的方法,就是一个简单的连接oracle的封装*/
        if (rs != null) {
            while (rs.next()) {
                if (userPara.getPassword().equals(rs.getString("PASSWORD"))) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 判断用户是否存在
     * 
     * @param userName
     * @return
     * @throws Exception
     */
    public boolean checkUser(String userName) throws Exception {
        String sql = "SELECT NAME FROM C_USER WHERE NAME=?\n";
        ResultSet rs = DaoUtil.executeQuery(DaoTools.getConnName(), sql,
                new String[] { userName });
        if (rs != null) {
            while (rs.next()) {
                return true;
            }
        }
        return false;
    }


    /**
     * 根据用户名判断是否有过登录记录
     */
    public boolean checkLoginRecord(String userName) throws Exception {
        String sql = "SELECT COUNT(*) num FROM C_LOGIN_RECORD WHERE USERNAME=?\n ";
        ResultSet rs = DaoUtil.executeQuery(DaoTools.getConnName(), sql,
                new String[] { userName });
        if (rs != null) {
            while (rs.next()) {
                if ("0".equals(rs.getString("num"))) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 删除用户的登录记录
     * 
     * @param userName
     * @throws Exception
     */
    public void deleteLoginRecord(String userName) throws Exception {
        String sql = "DELETE FROM C_LOGIN_RECORD WHERE USERNAME=? \n";
        DaoUtil.executeUpdate(DaoTools.getConnName(), sql,
                new String[] { userName });
    }

    /**
     * 获取用户最近的一条登录记录
     * 
     * @param userName
     * @return
     * @throws Exception
     */
    public ResultSet getLatestLoginRecord(String userName) throws Exception {
        String sql = "SELECT USERNAME, LOCK_FLAG, FAILURE_NUM, LOGIN_DATE "
                + " FROM C_LOGIN_RECORD WHERE  LOGIN_DATE=(SELECT MAX(LOGIN_DATE)"
                + "FROM C_LOGIN_RECORD WHERE USERNAME=? GROUP BY USERNAME)";
        return DaoUtil.executeQuery(DaoTools.getConnName(), sql,
                new String[] { userName });

    }

    /**
     * 获取用户登录失败次数为2的登录登录时间
     * @param userName
     * @return
     * @throws Exception
     */
    public String getFaNum2Record(String userName) throws Exception {
        String sql = "SELECT USERNAME,LOGIN_DATE FROM C_LOGIN_RECORD "
                + "  WHERE USERNAME=? AND FAILURE_NUM=2";
        ResultSet rs = DaoUtil.executeQuery(DaoTools.getConnName(), sql,
                new String[] { userName });
        if (rs != null) {
            while (rs.next()) {
                return rs.getString("LOGIN_DATE").replace("T", " ");
            }
        }
        return "";
    }

    /**
     * 插入登录记录
     * @param userName
     * @param lockFlag
     * @param failureNum
     */
    public void insertLoginRecord(String userName, String lockFlag,
            String failureNum) {
        List<String> list=new ArrayList<String>();
        String sql="INSERT INTO C_LOGIN_RECORD(USERNAME,LOCK_FLAG,FAILURE_NUM," +
        "LOGIN_DATE) values(? ,? ,? , sysdate)";
        list.add(userName);
        list.add(lockFlag);
        list.add(failureNum);
        DaoUtil.executeUpdate(DaoTools.getConnName(), sql, list.toArray());
    }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122

第三步,servlet中进行校验

LoginServlet.java
public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String userName = request.getParameter("username");
        String passWord = request.getParameter("password");
        UserPara userPara = new UserPara(userName, passWord);
        UserParaService service = new UserParaService();/*service层是对dao层的封装,里面加上了一些基本的转换方法*/
        try {
            if (service.checkUser(userName)) {
                // 用户存在
                if (service.checkLoginRecord(userName)) {
                    // 用户有过登录记录
                    ResultSet rs = service.getLatestLoginRecord(userName);
                    String lockFlag = "";
                    String failureNum = "";
                    String loginDate = "";
                    if (rs != null && rs.next()) {
                        lockFlag = rs.getString("LOCK_FLAG");
                        failureNum = rs.getString("FAILURE_NUM");
                        loginDate = rs.getString("LOGIN_DATE").replace("T", " ");
                    }
                    if ("1".equals(lockFlag)) {
                        // 用户被锁定
                        if (service.localdateLtDate2(loginDate)) {
                            // 锁定时间超过一天
                            //删除用户的登录记录
                            service.deleteLoginRecord(userName);
                            if(service.checkNameAndPsw(userPara)){
                                //用户名和密码匹配
                                service.insertLoginRecord(userName, "0", "0");
                                request.getSession().setAttribute("LoginFlag", "1");
                                response.sendRedirect("http://localhost:8080/web/prepay/pur/emp/ePricePara.do?action=init");
                                return;
                            }else{
                                //用户名密码不匹配
                                service.insertLoginRecord(userName, "0", "1");
                                response.sendRedirect("http://localhost:8080/web/prepay/pur/login/login.jsp?error=2");
                                return;
                            }

                        } else {
                            // 锁定时间未满一天
                            response.sendRedirect("http://localhost:8080/web/prepay/pur/login/login.jsp?error=3");
                            return;
                        }

                    } else {
                        // 用户未被锁定
                        if(service.checkNameAndPsw(userPara)){
                            //用户名密码匹配
                            service.deleteLoginRecord(userName);
                            service.insertLoginRecord(userName, "0", "0");
                            request.getSession().setAttribute("LoginFlag", "1");
                            response.sendRedirect("http://localhost:8080/web/prepay/pur/emp/ePricePara.do?action=init");
                            return;
                        }else{
                            //用户名密码不匹配
                            if(service.localdateLtDate(loginDate)){
                                //距离上次登录失败超过5分钟
                                service.deleteLoginRecord(userName);
                                service.insertLoginRecord(userName, "0", "1");
                                response.sendRedirect("http://localhost:8080/web/prepay/pur/login/login.jsp?error=2");
                                return;
                            }else{
                                //未超过5分钟
                                if("2".equals(failureNum)){
                                    //上次登录失败时已错误两次
                                    String date1=service.getFaNum2Record(userName);
                                    if(service.localdateLtDate(date1)){
                                        //距第一次登录错误时间大于5分钟
                                        service.deleteLoginRecord(userName);
                                        service.insertLoginRecord(userName, "0", "1");
                                        response.sendRedirect("http://localhost:8080/web/prepay/pur/login/login.jsp?error=2");
                                        return;

                                    }else{
                                        //在5分钟以内
                                        service.insertLoginRecord(userName, "1", "3");
                                        response.sendRedirect("http://localhost:8080/web/prepay/pur/login/login.jsp?error=4");
                                        return;
                                    }
                                }else{
                                    //上次登录失败时没超过两次
                                    service.insertLoginRecord(userName, "0", String.valueOf((Integer.parseInt(failureNum)+1)));
                                    response.sendRedirect("http://localhost:8080/web/prepay/pur/login/login.jsp?error=2");
                                    return;
                                }
                            }
                        }
                    }
                } else {
                    // 用户未有过登录记录
                    if(service.checkNameAndPsw(userPara)){
                        //用户名密码匹配
                        service.insertLoginRecord(userName, "0", "0");
                        request.getSession().setAttribute("LoginFlag", "1");
                        response.sendRedirect("http://localhost:8080/web/prepay/pur/emp/ePricePara.do?action=init");
                        return;

                    }else{
                        //用户名密码不匹配
                        service.insertLoginRecord(userName, "0", "1");
                        response.sendRedirect("http://localhost:8080/web/prepay/pur/login/login.jsp?error=2");
                        return;

                    }
                }
            } else {
                // 用户不存在
                response.sendRedirect("http://localhost:8080/web/prepay/pur/login/login.jsp?error=1");
                return;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116

service层的部分代码:

UserParaService.java
/**
     *判断当前时间与给定时间差是否大于5分钟 
     * @param date
     * @return 大于5分钟返回true
     * @throws Exception
     */
    public boolean localdateLtDate(String date) throws Exception{
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd HH:mm:ss");

        Date date1=sdf.parse(date);
        Date now=sdf.parse(sdf.format(new Date()));
        if(now.getTime()-date1.getTime()>5*60*1000){
            return true;
        }
        else{
            return false;
        }
    }


    /**
     *判断当前时间与给定时间差是否大于一天 
     * @param date
     * @return 大于一天返回true
     * @throws Exception
     */
    public boolean localdateLtDate2(String date) throws Exception{
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd HH:mm:ss");
        Date date1=sdf.parse(date);
        Date now=sdf.parse(sdf.format(new Date()));
        if(now.getTime()-date1.getTime()>24*60*60*1000){
            return true;
        }
        else{
            return false;
        }
    }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

登录jsp的js处理:

<script>

document.body.onload=function(){
var errori='<%=request.getParameter("error")%>';
  if(errori=='1'){
    alert("用户不存在!");
  }else if(errori=='2'){
          alert('用户名密码不匹配!');
  }else if(errori=='3'){
      alert("用户处于锁定状态!");}
  else if(errori=='4'){
      alert('密码连续3次输入错误,用户将被锁定24小时!');
      }
  if(document.myform.username.value==''&&document.myform.password.value==''){
    document.myform.username.focus();
    }
}
function EnterPress(e){
  var e = e || window.event;
  if(e.keyCode == 13){
    checkuser();
  }
}

function checkuser(){
  var forma=document.forms[0];
  if(forma.username.value.length>1&&forma.password.value.length>1){
    return true;
  }else{
    alert('用户名或密码不能为空');
    return false;
  }
}
</script>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

基本的逻辑就是这样,流程图当时随手画的,被扔掉了,有不对的地方欢迎大家指正。




(function () {('pre.prettyprint code').each(function () {
var lines = (this).text().split(\n).length;var numbering = $('
    ').addClass('pre-numbering').hide();
    (this).addClass(hasnumbering).parent().append( numbering);
    for (i = 1; i <= lines; i++) {
    numbering.append( ('
    • ').text(i));
      };
      $numbering.fadeIn(1700);
      });
      });
    • 4
      点赞
    • 17
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值