1. 程式人生 > >Java過濾器案例

Java過濾器案例

實現自動登入功能

編寫前端表單

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登入</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/DoLoginServlet">
    使用者:<input type="text" name="username"><
br> 密碼:<input type="password" name="password"><br> 有效期: 1分鐘:<input type="radio" value="${1*60}" name="time"> 5分鐘:<input type="radio" value="${5*60}" name="time"> 10分鐘:<input type="radio" value="${10*60}" name="time"><br> <input type="submit"
value="登入"> </form> </body> </html>

處理自動登入的Servlet

@WebServlet(name = "DoLoginServlet", urlPatterns = "/DoLoginServlet")
public class DoLoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username 
= request.getParameter("username"); String password = request.getParameter("password"); UserService userService = new UserService(); User user = userService.findUser(username, password); if (user == null) { request.setAttribute("message", "使用者名稱或密碼錯誤"); request.getRequestDispatcher("/message.jsp").forward(request,response); return; } // 使用者成功登入,設定登入,回寫Cookie request.getSession().setAttribute("user", user); Integer time = Integer.parseInt(request.getParameter("time")); // Cookie有效時間單位為秒 需*1000 Long expiresTime = System.currentTimeMillis() + time * 1000; Cookie cookie = makeCookie(user, expiresTime); cookie.setMaxAge(time); cookie.setPath("/"); response.addCookie(cookie); response.sendRedirect("/index.jsp"); } private Cookie makeCookie(User user, Long expiresTime) { // 使用者可以調整系統時間從而改變Cookie的有效期,Cookie的有效期應由服務端決定 // 單獨使用密碼進行MD5還是可能被破解,將三個欄位一起MD5來驗證Cookie的有效性 // autoLogin = username:expiresTime:md5(password:expiresTime:username) String cookieValue = user.getUsername() + ":" + expiresTime + ":" + WebUtils.md5(user.getUsername(),user.getPassword(),expiresTime); return new Cookie("autoLogin", cookieValue); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } }

模擬資料庫查使用者的Service

public class UserService {
    private static List<User> users;
    static {
        users = new ArrayList<>();
        users.add(new User("ak", "123"));
        users.add(new User("ai", "321"));
    }

    public User findUser(String username, String password) {
        for (User user : users) {
            if (user.getUsername().equals(username) && user.getPassword().equals(password)) {
                return user;
            }
        }
        return null;
    }

    public User findUser(String username) {
        for (User user : users) {
            if (user.getUsername().equals(username)) {
                return user;
            }
        }
        return null;
    }
}

生成MD5的工具類

public class WebUtils {

    public static String md5(String username,String password,Long expiresTime) {
        try {
            String md = password + ":" + expiresTime + ":" + username;
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(md.getBytes("utf-8"));
            Base64.Encoder encoder = Base64.getEncoder();
            return encoder.encodeToString(bytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

過濾器過濾所有請求

public class AutoLoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        // 檢查使用者是否登入
        User user = (User) req.getSession().getAttribute("user");
        if (user != null) {
            chain.doFilter(req, resp);
            return;
        }

        // 檢查使用者是否帶自動登入的Cookie
        Cookie autoLoginCookie = null;
        Cookie[] cookies = req.getCookies();
        for (int i = 0; cookies != null && i < cookies.length; i++) {
            if (cookies[i].getName().equals("autoLogin")) {
                autoLoginCookie = cookies[i];
            }
        }

        if (autoLoginCookie == null) {
            chain.doFilter(req, resp);
            return;
        }

        // 使用者帶了自動登入的Cookie,則先檢查Cookie的有效期
        String[] values = autoLoginCookie.getValue().split(":");
        if (values.length != 3) {
            chain.doFilter(req,resp);
            return;
        }

        long expiresTime = Long.parseLong(values[1]);
        if (System.currentTimeMillis() > expiresTime) {
            chain.doFilter(req, resp);
            return;
        }

        // 再檢查Cookie的有效性
        String username = values[0];
        UserService userService = new UserService();
        user = userService.findUser(username);
        if (user == null) {
            chain.doFilter(req, resp);
            return;
        }

        String server_md5 = WebUtils.md5(user.getUsername(), user.getPassword(), expiresTime);
        String client_md5 = values[2];
        if (!server_md5.equals(client_md5)) {
            chain.doFilter(req, resp);
            return;
        }

        // 執行登入
        req.getSession().setAttribute("user", user);
        chain.doFilter(req, resp);

    }

    @Override
    public void destroy() {

    }
}