案例四:实现用户自动登录的过滤器
在用户登录成功后,发送一个名称为user的cookie给客户端,cookie的值为用户名和md5加密后的密码。
编写一个AutoLoginFilter,这个filter检查用户是否带有名称为user的cookie来,如果有,则调用dao查询cookie的用户名和密码是否和数据库匹配,匹配则向session中存入user对象(即用户登录标记),以实现程序完成自动登录。
User类
package cn.itcast.domain;
/**
* Created by yvettee on 2017/10/24.
*/
public class User {
private String userName;
private String passWord;
public User(String userName, String passWord) {
super();
this.userName = userName;
this.passWord = passWord;
}
public User() {
super();
}
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;
}
}
BusinessService.java,用于给Web层提供业务服务
package cn.itcast.service;
import cn.itcast.domain.User;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yvettee on 2017/10/24.
*/
public class BusinessService {
private static List<User> list = new ArrayList();
static {
list.add(new User("aaa", "123"));
list.add(new User("bbb", "123"));
list.add(new User("ccc", "123"));
}
public User login(String userName, String passWord) {
for (User user : list) {
if (user.getUserName().equals(userName) && user.getPassWord().equals(passWord)) {
return user;
}
}
return null;
}
public User findUser(String userName) {
for (User user : list) {
if (user.getUserName().equals(userName)) {
return user;
}
}
return null;
}
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>login</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/loginServlet" method="post">
用户名:<input type="text" name="userName"><br/>
密码:<input type="password" name="passWord"><br/>
有效期:
1分钟<input type="radio" name="time" value="${1*60 }">
5分钟<input type="radio" name="time" value="${5*60 }">
10分钟<input type="radio" name="time" value="${10*60 }">
<br/>
<input type="submit" value="登陆">
</form>
</body>
</html>
LoginServlet
package cn.itcast.servlet;
import cn.itcast.domain.User;
import cn.itcast.service.BusinessService;
import sun.misc.BASE64Encoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.MessageDigest;
/**
* Created by yvettee on 2017/10/24.
*/
@WebServlet(name = "LoginServlet", urlPatterns = "/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userName = request.getParameter("userName");
String passWord = request.getParameter("passWord");
BusinessService service = new BusinessService();
User user = service.login(userName, passWord);
if (user == null) {
request.setAttribute("messgae", "用户名或密码错误!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}
//用户存在,存一个用户登录标记在session里
request.getSession().setAttribute("user", user);
//得到cookie的失效时间
int expiresTime = Integer.parseInt(request.getParameter("time"));
//给客户机发送自动登录的cookie
Cookie cookie = makeCookie(user, expiresTime);
response.addCookie(cookie);
response.sendRedirect("/index.jsp");
}
//给客户机发送自动登录的cookie的值为:username:md5(password)
//同时给cookie的值里面带一个失效时间(expiresTime),,即cookie的值为:username:expirestime:md5(password)
public Cookie makeCookie(User user, int expiresTime) {
long currentTime = System.currentTimeMillis();
String cookieValue = user.getUserName() + ":" + (currentTime + expiresTime * 1000) + ":" + md5(user.getUserName(), user.getPassWord(), (currentTime + expiresTime * 1000));
Cookie cookie = new Cookie("autoLogin", cookieValue);
cookie.setMaxAge(expiresTime);
cookie.setPath("/");
return cookie;
}
private String md5(String userName, String passWord, long expiresTime) {
try {
String value = passWord + ":" + expiresTime + ":" + userName;
MessageDigest md = MessageDigest.getInstance("md5");
byte md5[] = md.digest(value.getBytes());
BASE64Encoder encode = new BASE64Encoder();
return encode.encode(md5);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
配置过滤器
<filter>
<filter-name>AutoLoginFilter</filter-name>
<filter-class>cn.itcast.filter.AutoLoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AutoLoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
AutoLoginFilter
package cn.itcast.filter;
import cn.itcast.domain.User;
import cn.itcast.service.BusinessService;
import sun.misc.BASE64Encoder;
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.MessageDigest;
/**
* Created by yvettee on 2017/10/24.
*/
public class AutoLoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//检查用户是否登录
User user = (User) request.getSession().getAttribute("user");
if (user != null) {//登录继续执行下去
filterChain.doFilter(request, response);
return;
}
//没有登录,执行自动登录逻辑
//1.获得用户cookie
Cookie autoLoginCookie = null;
Cookie cookies[] = request.getCookies();
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals("autoLogin")) {
autoLoginCookie = cookies[i];
}
}
if (autoLoginCookie == null) {
filterChain.doFilter(request, response);
return;
}
//用户带了自动登录cookie,先检查cookie的有效期
String values[] = autoLoginCookie.getValue().split("\\:");
if (values.length != 3) {
filterChain.doFilter(request, response);
return;
}
long expiresTime = Long.parseLong(values[1]);
if (System.currentTimeMillis() > expiresTime) {
filterChain.doFilter(request, response);
return;
}
//再检查cookie的有效性,代表cookie时间有效
String userName = values[0];
String client_md5 = values[2];
BusinessService service = new BusinessService();
user = service.findUser(userName);
if (user == null) {
filterChain.doFilter(request, response);
return;
}
String server_md5 = md5(user.getUserName(), user.getPassWord(), expiresTime);
if (server_md5.equals(client_md5)) {
filterChain.doFilter(request, response);
return;
}
request.getSession().setAttribute("user", user);//执行登录
filterChain.doFilter(request, response);
}
private String md5(String userName, String passWord, long expiresTime) {
try {
String value = passWord + ":" + expiresTime + ":" + userName;
MessageDigest md = MessageDigest.getInstance("md5");
byte md5[] = md.digest(value.getBytes());
BASE64Encoder encode = new BASE64Encoder();
return encode.encode(md5);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void destroy() {
}
}
源代码:https://github.com/yvettee36/FilterBase
上篇:http://www.jianshu.com/p/95f5261838f7
下篇:Filter高级开发-增强request
网友评论