java登录程序用户密码5分钟内输错3次锁定用户账号一天的实现
2017-02-27 11:16
796 查看
最近在公司实习的项目遇到这么一个业务需求:用户登录时如果5分钟内密码连续3次输入错误就将用户锁定,24小时后自动解锁。
分析一下,这个需求有很多种方法可以实现,比较简单的就是采用数据库来实现,我采用的是比较老实的办法,欢迎大家留言指正。
公司开发采用的是struts1.1+Oracle+MVC,由于某些样式不支持的问题,用户登录数据的检验这些操作我都是传输到servlet中进行的。
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
[/code]
登录的时候直接往其中插入数据就好,这里c_id字段非空,是自动递增的,由于在oracle中没有自带的acto-increment,所以采用触发器+序列的方式来实现,代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
4000
9
10
11
12
13
14
15
[/code]
当往其中插入数据的时候,就会触发触发器,获得ID
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
[/code]
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
[/code]
service层的部分代码:
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
[/code]
登录jsp的js处理:
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
[/code]
基本的逻辑就是这样,流程图当时随手画的,被扔掉了,有不对的地方欢迎大家指正。
第一步建用户登录记录表
第二步完成dao层的方法
第三步servlet中进行校验
(function () {('pre.prettyprint code').each(function () {
var lines = (this).text().split(′\n′).length;varnumbering = $('').addClass('pre-numbering').hide();
(this).addClass(′has−numbering′).parent().append(numbering);
for (i = 1; i <= lines; i++) {
numbering.append(('
').text(i));
};
$numbering.fadeIn(1700);
});
});
分析一下,这个需求有很多种方法可以实现,比较简单的就是采用数据库来实现,我采用的是比较老实的办法,欢迎大家留言指正。
公司开发采用的是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
[/code]
登录的时候直接往其中插入数据就好,这里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
4000
9
10
11
12
13
14
15
[/code]
当往其中插入数据的时候,就会触发触发器,获得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
[/code]
第三步,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
[/code]
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
[/code]
登录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
[/code]
基本的逻辑就是这样,流程图当时随手画的,被扔掉了,有不对的地方欢迎大家指正。
第一步建用户登录记录表
第二步完成dao层的方法
第三步servlet中进行校验
(function () {('pre.prettyprint code').each(function () {
var lines = (this).text().split(′\n′).length;varnumbering = $('').addClass('pre-numbering').hide();
(this).addClass(′has−numbering′).parent().append(numbering);
for (i = 1; i <= lines; i++) {
numbering.append(('
').text(i));
};
$numbering.fadeIn(1700);
});
});
相关文章推荐
- java登录程序用户密码5分钟内输错3次锁定用户账号一天的实现
- java登录程序用户密码5分钟内输错3次锁定用户账号一天的实现
- Java小程序之集合框架模拟数据库实现用户登录和注册功能
- python实现简单的用户密码登录控制(输入三次就锁定用户)
- django实现登录时候输入密码错误5次锁定用户十分钟
- 编写代码实现,模拟用户登录情景,并且只能登录三次。 只允许输入三次密码,如果密码正确则提示登录成,如果三次均输入错误,则退出程序。
- python实现简单的用户密码登录控制(输入三次就锁定用户)
- Java中SpringSecurity密码错误5次锁定用户的实现方法
- Java小程序之集合框架模拟数据库实现用户登录和注册功能
- 编写代码实现,模拟用户登录情景,并且只能登录三次,只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序。
- java加密用户登录密码--不用MD5实现
- Java实现账号密码登录窗口(包含修改密码等)
- java_web 记录用户自动登录用户密码 模块的实现
- python用户登录,密码错误3次则锁定
- 编写一个jsp程序,实现用户登录,当用户输入的用户或密码错误时,将页面重定向到错误提示页,并在该页面显示30秒后 自动回到用户登录界面
- C#序列化实现用户登录记住账号密码功能
- java实现微信小程序第三方登录-保存用户至自己的服务器
- C语言怎么将用户账号密码写入文件实现登录注册功能?
- C语言怎么将用户账号密码写入文件实现登录注册功能?
- django 实现登录时候输入密码错误5次锁定用户十分钟