一、记住密码的实现
记住密码我们可以通过cookie来实现,当用户登录时,若账号密码正确则为账号和密码创建cookie,再去判断是否勾选记住密码选项,若勾选上则设置cookie的有效时间为半小时,若没有勾选上则设置有效时间为0,用来刷新之前的cookie。
servlet
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
String ch = req.getParameter("ch");
System.out.println(ch);
UserService service = new UserServiceImpl();
User user = service.Login(uname, pwd);
if(user != null){
HttpSession session = req.getSession();
session.setAttribute("name",uname);
Cookie cookie1 = new Cookie("uname", uname);
Cookie cookie2 = new Cookie("pwd", pwd);
Cookie cookie3 = new Cookie("ch", ch);
// remeber to set cookie age
if(!ch.equals("checked")){
cookie1.setMaxAge(0);
cookie2.setMaxAge(0);
cookie3.setMaxAge(0);
}else{
cookie1.setMaxAge(60*60*10);
cookie2.setMaxAge(60*60*10);
cookie3.setMaxAge(60*60*10);
}
cookie1.setPath(req.getContextPath());
cookie2.setPath(req.getContextPath());
cookie3.setPath(req.getContextPath());
resp.addCookie(cookie1);
resp.addCookie(cookie2);
resp.addCookie(cookie3);
resp.sendRedirect(req.getContextPath()+"/success.jsp");
}else{
req.setAttribute("msg","uname or pwd is not correct!");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}
}
在jsp中,我们可以使用EL表达式来获取cookie中的uname、pwd和remeber属性,并用它们初始化input。
login.jsp
<body>
<%
String uname = "";
String pwd = "";
String checked = "";
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie:cookies){
if(cookie.getName().equals("uname")){
uname = cookie.getValue();
}
if(cookie.getName().equals("pwd")){
pwd = cookie.getValue();
}
if(cookie.getName().equals("ch")){
checked = cookie.getValue();
}
}
}
%>
<h3>登录页面</h3>
<form action="DoLogin" method="post">
<p>
用户名:<input type="text" name="uname" id="uname" value="<%=uname%>"/>
<span id="uname_span">
</span>
</p>
<p>
密码:<input type="password" name="pwd" id="pwd" value="<%=pwd%>"/>
<span id="pwd_span"></span>
</p>
<p>remeber me <input type="checkbox" <%=checked%> name="ch" value="checked"> </p>
<p>
<input type="submit" value="登录" />
</p>
没有账号,<a href="save.jsp">立即注册</a>
</form>
</body>
二、三次密码错误后锁定20s
- 第一步应该思考这个记录错误次数的属性(设该属性为error)应该存放在哪里,我们有四个作用域分别为page、request、session和application。若存放在page和request中的话,当页面刷新时这个属性就会重头开始,无法做到累加,若将error设在application中,则该属性会被所有用户共享,这不符合我们的需求,所以我们需要将该属性设置在session中。
- 我们来回顾一下session的声明周期:当客户端首次访问服务器时,服务器会返回给该客户端一个sessionId,此后这个客户端每次访问服务器都会带着这个sessionId(直到这个session过期或被销毁),服务器可以根据sessionId来找到该客户对应的session。
- 当密码错误时我们可以在servlet中将error的次数+1,若error>=3时执行session.setMaxInactiveAge(20)(当超过20s服务器与客户端没有交互时该session会被销毁),这样当用户过20s再访问服务器就会重新开始计算error
- 我们还应该在servlet开头加上一个判断:若error>=3则返回登录界面并执行return,这样可以提高程序效率。
protected void doLogin(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
String ename = req.getParameter("ename");
String pwd = req.getParameter("pwd");
String remeber = req.getParameter("remeber");
EmployeeService service = new EmployeeServiceImpl();
Employee employee = service.login(ename, pwd);
HttpSession session = req.getSession();
Integer err = (Integer) session.getAttribute("error");
if(err!=null && err>=3){
req.setAttribute("msg","已经输错三次,请勿重复登录");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
return ;
}
if(employee != null){
req.removeAttribute("msg");
session.removeAttribute("error");
Cookie uname = new Cookie("uname", ename);
Cookie pwd1 = new Cookie("pwd", pwd);
uname.setPath(req.getContextPath());
pwd1.setPath(req.getContextPath());
if("rp".equals(remeber)){
uname.setMaxAge(60*24*30);
pwd1.setMaxAge(60*24*30);
}else{
uname.setMaxAge(0);
pwd1.setMaxAge(0);
}
resp.addCookie(uname);
resp.addCookie(pwd1);
resp.sendRedirect(req.getContextPath()+"/index.html");
}else{
if(err == null){
err=1;
}else {
err++;
}
session.setAttribute("error",err);
if(err >= 3){
req.setAttribute("msg","连续登陆失败三次,锁定20s");
session.setMaxInactiveInterval(20);
}else {
req.setAttribute("msg", "账号或密码错误");
}
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>$Title$</title>
<base href="<%=request.getContextPath()+"/"%>">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="renderer" content="webkit">
<title>登录</title>
<link rel="stylesheet" href="css/pintuer.css">
<link rel="stylesheet" href="css/admin.css">
<script src="js/jquery.js"></script>
<script src="js/pintuer.js"></script>
<script type="text/javascript">
window.onload = function (){
<c:if test="${requestScope.msg!=null}">
alert('${requestScope.msg}')
</c:if>
<c:if test="${sessionScope.error!=null && sessionScope.error>=3}">
var flag = 20;
var btn = document.getElementById('sub')
btn.disabled = true
var timer = setInterval(()=>{
flag--;
if(flag <=0){
btn.disabled = false
clearInterval(timer)
}
},1000)
</c:if>
}
</script>
</head>
<body>
<div class="bg"></div>
<div class="container">
<div class="line bouncein">
<div class="xs6 xm4 xs3-move xm4-move">
<div style="height:150px;"></div>
<div class="media media-y margin-big-bottom">
</div>
<form action="EmployeeServlet?method=doLogin" method="post">
<div class="panel loginbox">
<div class="text-center margin-big padding-big-top"><h1>后台管理中心</h1></div>
<div class="panel-body" style="padding:30px; padding-bottom:10px; padding-top:10px;">
<div class="form-group">
<div class="field field-icon-right">
<input type="text" class="input input-big" name="ename" placeholder="登录账号" data-validate="required:请填写账号" value="${cookie.uname.value}" />${requestScope.msg}
<span class="icon icon-user margin-small"></span>
</div>
</div>
<div class="form-group">
<div class="field field-icon-right">
<input type="password" class="input input-big" name="pwd" placeholder="登录密码" data-validate="required:请填写密码" value="${cookie.pwd.value}"/>
<span class="icon icon-key margin-small"></span>
</div>
</div>
<div class="form-group">
<div class="field">
<input type="text" class="input input-big" name="code" placeholder="填写右侧的验证码" data-validate="required:请填写右侧的验证码" />
<img src="images/passcode.jpg" alt="" width="100" height="32" class="passcode" style="height:43px;cursor:pointer;" onclick="this.src=this.src+'?'">
</div>
</div>
</div>
<div style="padding:30px;"><input type="submit" class="button button-block bg-main text-big input-big" value="登录" id="sub" ></div>
<p>记住密码<input name="remeber" type="checkbox" value="rp" ${cookie.remeber.value.equals("rp")?"checked" : ""}></p>
</div>
</form>
</div>
</div>
</div>
</body>
</html>