自动登录原理
利用cookie保存用户登录信息,从cookie中获取用户名和密码,不需要用户自己再次输入
为什么用Filter
如果不用Filter,请求每个servlet时,都要有操作cookie的相同代码来处理自动登录,由于filter能够拦截请求,那么我们可以提取相同的代码到filter中,在filter中处理自动登录。
创建user
public class User {
private String username;
private String password;
private Integer autoLoginTime;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAutoLoginTime() {
return autoLoginTime;
}
public void setAutoLoginTime(Integer autoLoginTime) {
this.autoLoginTime = autoLoginTime;
}
}
创建IndexServlet,显示网站首页
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 解决乱码问题
response.setContentType("text/html;charset=utf-8");
// 创建或者获取保存用户信息的Session对象
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
if (user == null) {
response.getWriter().print("您还没有登录,请<a href='"+request.getContextPath()+"/login.html'>登录 </a>");
} else {
response.getWriter().print("您已登录,欢迎你," + user.getUsername() + "!");
response.getWriter().print("<a href='"+request.getContextPath()+"/LogoutServlet'>退出</a>");
// 创建Cookie存放Session的标识号
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(60 * 60 * 24);
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
实现登录页面login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<script src="js/axios-0.18.0.js"></script>
</head>
<body style="text-align: center;">
<center><h3>用户登录</h3></center>
<form action="" method="post">
<table border="1" width="600px" cellpadding="0" cellspacing="0"
align="center" >
<tr>
<td height="30" align="center">用户名:</td>
<td>
<input type="text" id="username" name="username" />
<span id="errerMsg"></span>
</td>
</tr>
<tr>
<td height="30" align="center">密 码:</td>
<td>
<input type="password" id="password" name="password" /></td>
</tr>
<tr>
<td height="35" align="center">自动登录时间</td>
<td><input type="radio" name="autologinTime"
value="60*60*24*31" />一个月
<input type="radio" name="autologinTime"
value="60*60*24*31*3" />三个月
<input type="radio" name="autologinTime"
value="60*60*24*31*6" />半年
<input type="radio" name="autologinTime"
value="60*60*24*31*12" />一年
</td>
</tr>
<tr>
<td height="30" colspan="2" align="center">
<input type="button" id="login-button" value="登录" />
<input type="reset" value="重置" />
</td>
</tr>
</table>
</form>
</body>
<script>
function getAutologinTime(autologin) {
autologinTime=0;
switch (autologin) {
case "60*60*24*31": autologinTime=60*60*24*31;break;
case "60*60*24*31*3": autologinTime=60*60*24*31*3;break;
case "60*60*24*31*6": autologinTime=60*60*24*31*6;break;
case "60*60*24*31*12": autologinTime=60*60*24*31*12;break;
}
return autologinTime;
}
//1. 给按钮绑定单击事件
document.getElementById("login-button").onclick = function () {
// 将表单数据转为json
var formData = {
username:"",
password:"",
autologinTime:0
};
// 获取表单数据
let username = document.getElementById("username").value;
// 设置数据
formData.username = username;
// 获取表单数据
let password = document.getElementById("password").value;
// 设置数据
formData.password = password;
let autologinTime = document.getElementsByName("autologinTime");
for (let i = 0; i < autologinTime.length; i++) {
if(autologinTime[i].checked){
//
formData.autologinTime = getAutologinTime(autologinTime[i].value);
}
}
console.log(formData);
axios.post('http://localhost:80/LoginServlet', formData)
.then(function (response) {
if (response.data.status==401){
document.getElementById("errerMsg").innerText=response.data.data;
}else if (response.data.status== 302){
location.href=response.data.data;
}
})
.catch(function (error) {
console.log(error);
});
}
</script>
<html>
创建两个servlet处理登录和退出
LoginServlet
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/json;charset=utf-8");
BufferedReader reader = request.getReader();
String s = reader.readLine();
User user = JSON.parseObject(s, User.class);
// 获得用户名和密码
String username = user.getUsername();
String password = user.getPassword();
// 检查用户名和密码
if ("a".equals(username) && "a".equals(password)) {
// 登录成功
// 将用户状态 user 对象存入 session域
request.getSession().setAttribute("user", user);
// 获取用户选择的自动登录有效时间
Integer autoLoginTime = user.getAutoLoginTime();
if (autoLoginTime != null && autoLoginTime>0) {
// 注意 cookie 中的密码要加密
Cookie cookie = new Cookie("autoLogin", username + "-"
+ password);
cookie.setMaxAge(autoLoginTime);
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
}
Result r = new Result();
r.setStatus(302);
r.setData(request.getContextPath()+"/IndexServlet");
// 跳转至首页
response.getWriter().write(JSON.toJSONString(r));
} else {
Result r = new Result();
r.setStatus(401);
r.setData("用户名或密码错");
response.getWriter().write(JSON.toJSONString(r));
}
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
LogoutServlet
public class LogoutServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// 用户注销
request.getSession().removeAttribute("user");
// 从客户端删除自动登录的cookie
Cookie cookie = new Cookie("autoLogin", "msg");
cookie.setPath(request.getContextPath());
cookie.setMaxAge(0);
response.addCookie(cookie);
response.sendRedirect(request.getContextPath()+"/IndexServlet");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
创建过滤器AutoLoginFilter
@WebFilter(filterName = "AutoLoginFilter",urlPatterns = "/*")
public class AutoLoginFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
//判断用户是否已经登录,如果登录了,不用再去处理cookie
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
if (user == null){
autoLogin(request);
}
// 放行
chain.doFilter(request, response);
}
private void autoLogin(HttpServletRequest request) {
// 获得一个名为 autologin 的cookie
Cookie[] cookies = request.getCookies();
String autologin = null;
for (int i = 0; cookies != null && i < cookies.length; i++) {
if ("autoLogin".equals(cookies[i].getName())) {
// 找到了指定的cookie
autologin = cookies[i].getValue();
break;
}
}
if (autologin != null) {
// 做自动登录
String[] parts = autologin.split("-");
String username = parts[0];
String password = parts[1];
// 检查用户名和密码
if ("a".equals(username)&& ("a").equals(password)) {
// 登录成功,将用户状态 user 对象存入 session域
User user = new User();
user.setUsername(username);
user.setPassword(password);
request.getSession().setAttribute("user", user);
}
}
}
public void destroy() {
}
}
运行项目,查看结果
http://localhost:8080/chapter08/login.html
输入用户名、密码,选择自动登录时间
点击”登录“,结果如下
此时,再打开一个相同的浏览器,访问首页,结果如下
说明实现了自动登录功能。
单击”注销“,结果如下
再开启一个相同的浏览器,访问首页,结果如上,说明cookie被删除了,也说明自动登录功能只有在用户登录期间才可用。