使用Filter实现用户自动登录

自动登录原理

利用cookie保存用户登录信息,从cookie中获取用户名和密码,不需要用户自己再次输入


为什么用Filter

如果不用Filter,请求每个servlet时,都要有操作cookie的相同代码来处理自动登录,由于filter能够拦截请求,那么我们可以提取相同的代码到filter中,在filter中处理自动登录。


创建user

public class User {
    private String username;
    private String password;
    private Integer autoLoginTime;
    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;
    }

    public Integer getAutoLoginTime() {
        return autoLoginTime;
    }

    public void setAutoLoginTime(Integer autoLoginTime) {
        this.autoLoginTime = autoLoginTime;
    }
}

创建IndexServlet,显示网站首页

public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 解决乱码问题
        response.setContentType("text/html;charset=utf-8");
        // 创建或者获取保存用户信息的Session对象
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            response.getWriter().print("您还没有登录,请<a href='"+request.getContextPath()+"/login.html'>登录   </a>");
        } else {
            response.getWriter().print("您已登录,欢迎你," + user.getUsername() + "!");
            response.getWriter().print("<a href='"+request.getContextPath()+"/LogoutServlet'>退出</a>");
            // 创建Cookie存放Session的标识号
            Cookie cookie = new Cookie("JSESSIONID", session.getId());
            cookie.setMaxAge(60 * 60 * 24);
            cookie.setPath(request.getContextPath());
            response.addCookie(cookie);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

实现登录页面login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
    <script src="js/axios-0.18.0.js"></script>
</head>

<body style="text-align: center;">

<center><h3>用户登录</h3></center>
<form action=""  method="post">
    <table border="1" width="600px" cellpadding="0" cellspacing="0"
           align="center" >
        <tr>
            <td height="30" align="center">用户名:</td>
            <td>&nbsp;&nbsp;
                <input type="text" id="username" name="username" />
                <span id="errerMsg"></span>
            </td>
        </tr>
        <tr>
            <td height="30" align="center">密   &nbsp; 码:</td>
            <td>&nbsp;&nbsp;
                <input type="password" id="password" name="password" /></td>
        </tr>
        <tr>
            <td height="35" align="center">自动登录时间</td>
            <td><input type="radio" name="autologinTime"
                       value="60*60*24*31" />一个月
                <input type="radio" name="autologinTime"
                       value="60*60*24*31*3" />三个月
                <input type="radio" name="autologinTime"
                       value="60*60*24*31*6" />半年
                <input type="radio" name="autologinTime"
                       value="60*60*24*31*12" />一年
            </td>
        </tr>
        <tr>
            <td height="30" colspan="2" align="center">
                <input type="button" id="login-button" value="登录" />
                &nbsp;&nbsp;&nbsp;&nbsp;
                <input type="reset" value="重置" />
            </td>
        </tr>
    </table>
</form>
</body>
<script>
    function getAutologinTime(autologin) {
        autologinTime=0;
        switch (autologin) {
            case "60*60*24*31": autologinTime=60*60*24*31;break;
            case "60*60*24*31*3": autologinTime=60*60*24*31*3;break;
            case "60*60*24*31*6": autologinTime=60*60*24*31*6;break;
            case "60*60*24*31*12": autologinTime=60*60*24*31*12;break;
        }
        return autologinTime;
    }

    //1. 给按钮绑定单击事件
    document.getElementById("login-button").onclick = function () {
        // 将表单数据转为json
        var formData = {
            username:"",
            password:"",
            autologinTime:0
        };
        // 获取表单数据
        let username = document.getElementById("username").value;
        // 设置数据
        formData.username = username;

        // 获取表单数据
        let password = document.getElementById("password").value;
        // 设置数据
        formData.password = password;

        let autologinTime = document.getElementsByName("autologinTime");
        for (let i = 0; i < autologinTime.length; i++) {
            if(autologinTime[i].checked){
                //
                formData.autologinTime = getAutologinTime(autologinTime[i].value);
            }
        }
        console.log(formData);
    axios.post('http://localhost:80/LoginServlet', formData)
        .then(function (response) {
            if (response.data.status==401){
                document.getElementById("errerMsg").innerText=response.data.data;
            }else if (response.data.status== 302){
                location.href=response.data.data;
            }

        })
        .catch(function (error) {
            console.log(error);
        });
    }
</script>
<html>

创建两个servlet处理登录和退出

LoginServlet

public class LoginServlet extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/json;charset=utf-8");
        BufferedReader reader = request.getReader();
        String s = reader.readLine();
        User user = JSON.parseObject(s, User.class);
        // 获得用户名和密码
        String username = user.getUsername();
        String password = user.getPassword();
        // 检查用户名和密码
        if ("a".equals(username) && "a".equals(password)) {
            // 登录成功
            // 将用户状态 user 对象存入 session域

            request.getSession().setAttribute("user", user);
            // 获取用户选择的自动登录有效时间
            Integer autoLoginTime = user.getAutoLoginTime();
            if (autoLoginTime != null && autoLoginTime>0) {
                // 注意 cookie 中的密码要加密
                Cookie cookie = new Cookie("autoLogin", username + "-"
                        + password);
                cookie.setMaxAge(autoLoginTime);
                cookie.setPath(request.getContextPath());
                response.addCookie(cookie);
            }
            Result r = new Result();
            r.setStatus(302);
            r.setData(request.getContextPath()+"/IndexServlet");
            // 跳转至首页
            response.getWriter().write(JSON.toJSONString(r));
        } else {
            Result r = new Result();
            r.setStatus(401);
            r.setData("用户名或密码错");

            response.getWriter().write(JSON.toJSONString(r));
        }
    }
    public void doPost(HttpServletRequest request,
                       HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

LogoutServlet

public class LogoutServlet extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
            throws ServletException, IOException {
        // 用户注销
        request.getSession().removeAttribute("user");
        // 从客户端删除自动登录的cookie
        Cookie cookie = new Cookie("autoLogin", "msg");
        cookie.setPath(request.getContextPath());
        cookie.setMaxAge(0);
        response.addCookie(cookie);
        response.sendRedirect(request.getContextPath()+"/IndexServlet");
    }
    public void doPost(HttpServletRequest request,
                       HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

创建过滤器AutoLoginFilter

@WebFilter(filterName = "AutoLoginFilter",urlPatterns = "/*")
public class AutoLoginFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    public void doFilter(ServletRequest req, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        //判断用户是否已经登录,如果登录了,不用再去处理cookie
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null){
            autoLogin(request);
        }

        // 放行
        chain.doFilter(request, response);
    }

    private void autoLogin(HttpServletRequest request) {
        // 获得一个名为 autologin 的cookie
        Cookie[] cookies = request.getCookies();
        String autologin = null;
        for (int i = 0; cookies != null && i < cookies.length; i++) {
            if ("autoLogin".equals(cookies[i].getName())) {
                // 找到了指定的cookie
                autologin = cookies[i].getValue();
                break;
            }
        }
        if (autologin != null) {
            // 做自动登录
            String[] parts = autologin.split("-");
            String username = parts[0];
            String password = parts[1];
            // 检查用户名和密码
            if ("a".equals(username)&& ("a").equals(password)) {
                // 登录成功,将用户状态 user 对象存入 session域
                User user = new User();
                user.setUsername(username);
                user.setPassword(password);
                request.getSession().setAttribute("user", user);
            }
        }
    }

    public void destroy() {
    }
}

运行项目,查看结果

http://localhost:8080/chapter08/login.html

输入用户名、密码,选择自动登录时间

 点击”登录“,结果如下

 此时,再打开一个相同的浏览器,访问首页,结果如下 

 说明实现了自动登录功能。

单击”注销“,结果如下

 再开启一个相同的浏览器,访问首页,结果如上,说明cookie被删除了,也说明自动登录功能只有在用户登录期间才可用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值