ThoughtWorks欧亚创新工作室学习资源JavaEE 学习专题

Filter案例四—实现用户自动登录的过滤器

2017-10-24  本文已影响32人  小小蒜头

案例四:实现用户自动登录的过滤器

在用户登录成功后,发送一个名称为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

上一篇 下一篇

猜你喜欢

热点阅读