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

    }
}

 

转载于:https://www.cnblogs.com/aikf/p/10126377.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值