Java過濾器案例

實現自動登陸功能

編寫前端表單html

<%@ 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);
    }
}

模擬數據庫查用戶的Servicejava

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);
        }
    }
}

過濾器攔截全部請求cookie

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() {

    }
}
相關文章
相關標籤/搜索