最近在公司实习的项目遇到这么一个业务需求:用户登录时如果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_tgbefore insert on C_LOGIN_RECORDfor each row
beginselect 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 blocke.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

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

  • 第一步建用户登录记录表
  • 第二步完成dao层的方法
  • 第三步servlet中进行校验

(function () {(function () { ('pre.prettyprint code').each(function () {
var lines = (this).text().split(′\n′).length;var(this).text().split('\n').length; var numbering = $(' ').addClass('pre-numbering').hide();
(this).addClass(′has−numbering′).parent().append((this).addClass('has-numbering').parent().append(numbering);
for (i = 1; i <= lines; i++) {
numbering.append(numbering.append(('

  • ').text(i));
    };
    $numbering.fadeIn(1700);
    });
    });

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

  1. 渗透实战:dedeCMS任意用户密码重置到内网getshell

    渗透实战:dedeCMS任意用户密码重置到内网getshell ## 一.简介 DedeCMS 是一个基于 PHP 和 MySQL 的开源 CMS 系统,它是国内很多网站使用的 CMS 系统之一.在使 ...

  2. Python3.5 Day1作业:实现用户密码登录,输错三次锁定。

    作业需求: 1.输入用户名密码 2.认证成功后显示欢迎信息 3.输错三次后锁定 实现思路: 1.判断用户是否在黑名单,如果在黑名单提示账号锁定. 2.判断用户是否存在,如果不存在提示账号不存在. 3. ...

  3. java后台实现用户密码登录和手机短信登录

    1.账号密码登录:获取用户名.密码,检验是否存在该账号,以及该账号是否有效(未冻结.未删除),检验密码是否正确 public Result<JSONObject> login(@Reque ...

  4. vr设备应用程序_在15分钟内构建一个VR Web应用程序

    vr设备应用程序 在15分钟内,您可以开发一个虚拟现实应用程序,并在Web浏览器,VR头盔或Google Daydream上运行它. 关键是A-Frame ,这是Mozilla VR Team构建的开 ...

  5. iPhone忘记锁屏密码,多次输错被禁用?三种方法轻松解决!

    为了保证手机的隐私安全,我们通常会将手机设置锁屏密码.最近有许多果粉反馈,自己长期不用的iPhone 忘记锁屏密码打不开了,多次输错密码还被禁用了,怎么办? 今天,小编就针对苹果手机忘记锁屏密码这个问 ...

  6. (Java)实现一个用户密码登录的弹窗界面

    目录 一.前言 二.涉及到的知识点代码 三.代码部分 四.程序运行结果(弹出) 一.前言 1.本代码是我在上学时写的,有一些地方没能完美实现,请包涵也请多赐教! 2.本弹窗界面可以根据简单的要求进行输 ...

  7. java登录中用户类型分类_基于用户登陆的struts2中action的分类详解

    在struts2中action的分类有:继承 ActionSupport 实现 Action,模型驱动(ModelDriven)的 Action,多方法的 Action三种方式. 1.继承 Actio ...

  8. java修改ldap用户密码_LDAP 用户更改自己的密码

    LDAP中采用了ACL的权限控制. 在/etc/openldap/slapd.conf文件中:# # See slapd.conf(5) for details on configuration op ...

  9. Java小程序:分别计算1-100内的奇数和偶数的和

    代码如下: /*** 2.1-100所有的奇数和.偶数和*/ public class Sum100 {public static void main(String[] args) {//计算1-10 ...

最新文章

  1. mysql.err日志分析_Mysql日志解析
  2. Instagram个性化推荐工程中三个关键技术是什么?
  3. Swift教程之控制流
  4. python高效 二分法查找
  5. 关于 spring-aop理解
  6. python用于什么-python用于什么
  7. 海淘会不会成为电商的下一片蓝海?
  8. html 分割线_零基础网页设计/前端/html,第四课:前三课总结,以及单标签img
  9. ES语法及-IK分词器
  10. 8本前沿技术书,助力这届「青年人」将科幻变成现实
  11. C#算法设计查找篇之05-二叉树查找
  12. 面试问题_教资面试,结构化面试问题分享
  13. Qt4_子类化QMainWindow
  14. mysql 乐观锁和悲观锁,MySQL中的悲观锁与乐观锁
  15. Python中self的用法详解(链接传送)
  16. 论通过测试与失败测试
  17. SOTA级发丝抠图模型PP-Matting开源,支持多场景精细化分割
  18. LaTeX安装环境和软件下载地址
  19. k8s FailedCreatePodSandBox: Failed create pod sandbox
  20. 基于TCP Socket和Websocket实现的相互即时通信系统

热门文章

  1. 数据库SQ_lite的基础用法
  2. Failed to execute script ‘xxx‘ due to unhandled exception:No module named ‘ctypes‘
  3. 读书笔记:《高频交易员》
  4. java后端语言,后端开发语言哪一种比较好?后端开发语言比较
  5. 股票知识:(一)投资名言
  6. OpenFace使用OpenFace进行人脸识别
  7. PXE kickstart 安装时候出现/dev/root does not exits
  8. 使用组策略部署Office2007兼容包不能成功|SoftwareInstallation107108
  9. 合服 两个服务器都有什么作用,S2赛季转服功能介绍 第二赛季合服转服注意事项...
  10. 自动驾驶列车已准备就绪!但你敢坐吗?