您的位置:首页 > 编程语言 > Java开发

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

2017-02-27 11:16 796 查看
最近在公司实习的项目遇到这么一个业务需求:用户登录时如果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
[/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-锁定账号
相关文章推荐