2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > java登录程序用户密码5分钟内输错3次锁定用户账号一天的实现

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

时间:2023-06-15 21:50:27

相关推荐

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--登录时间,默认为当前时间)1234567812345678

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

-- Create sequence create sequence LOGIN_AUTOINC_SEQminvalue 1maxvalue 99999999start with 43increment by 1nocacheorder;-- Create trigger create or replace trigger login_autoinc_tgbefore insert on C_LOGIN_RECORDfor each rowbeginselect login_autoinc_seq.nextval into :new.c_id from dual;end login_autoinc_tg;123456789101112131415123456789101112131415

当往其中插入数据的时候,就会触发触发器,获得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());}12345678910111213141516171819222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119111221234567891011121314151617181922232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811911122

第三步,servlet中进行校验

LoginServlet.javapublic 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();}1234567891011121314151617181922232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511612345678910111213141516171819222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116

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;}}123456789101112131415161718192223242526272829303132333435363738123456789101112131415161718192223242526272829303132333435363738

登录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>12345678910111213141516171819222324252627282930313233341234567891011121314151617181922232425262728293031323334

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

第一步建用户登录记录表第二步完成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);

});

});

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。