Cookie实现自动登录的功能分析

自动登录功能十分常见,以下对个人用的一种方法进行分析

  1. 基本知识

    1. Cookie

      Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器,当用户使用浏览器再去访问服务器中的web资源时,会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。通俗讲,就是把上网留下的一些数据存放到磁盘中或者域中,然后下次上网就能自动加载一些数据。

    2. Cookie API

      Javax.servlet.http.Cookie类用于创建一个Cookie,response接口也定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。同样,request接口中也定义了一个getCookie方法,它用于获取客户端提交的cookie
      Public Cookie(String name, String value)
      setValue与getValue方法
      setMaxAge与getMaxAge方法

      setPath与getPath方法
      setDomain与getDomain方法
      getName方法

    3. 自动登录

      各种网站上都可以捡到,方面用户操作,但设计的不好或操作不当容易造成安全隐患,令用户信息泄漏。 

  2. 实现分析

     关键在于设计到底存放什么东西在Cookie里面,引用网上的说法:

  • Cookie只是一个普通的文本文件,那里面包含的字符串可以直接用记事本打开并进行编辑。因此任何人在任何电脑上都可以伪造一个包含有他人用户名 的 Cookie,从而实现对他人身份的冒用。要解决这个问题,就要在Cookie中附加一项信息,这个信息需要具有以下特性:1、和该用户一一对应;2、伪 造难度大。这些内容和用户名一起,以Cookie的形式发送给用户的浏览器。并且,服务器必须能够记住这项内容,以便用户再次访问的时候进行核对。  

  • 理论上,可以使用该用户的密码。密码具备了前述的两个特点。但是因为Cookie本身未经加密,保存于其中的密码(应该加密)可以被任何人看到,因此这个方法极不安全。  

  • 另一种可以加以利用的信息是用户访问时的Session id。因为Session id是一个由系统随机产生的、无规律的、长度较长的字符串,因此它很难被伪造。要把它和用户对应起来,我们需要在数据库中添加一个表,这个表至少有两个字 段,一个是用户名,一个是Session id。当用户首次登录的时候,我们把当前的Session id和用户名分别用Cookie发送给用户,同时,把这两项作为一条记录插入数据库。这样,当用户再次访问的时候,服务器就可以读取客户端发来的这两个 Cookie,并且用它们的值和数据库中的记录比对。如果在数据库中找到了相应记录,就说明这台电脑的确是该用户上次登录时使用的电脑,进而可以为该用户自动登录。 

个人就以useriD作为存放在Cookie中的数据为例,展示如何实现。

代码没有经过严格分层,使用静态数据模拟数据库。

代码部分

  1. User.java

  • public class User {
        private String userId;
        private String username;
        private String password;
        public String getUserId() {
            return userId;
        }
        public void setUserId(String userId) {
            this.userId = userId;
        }
        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;
        }
    }

LoginServlet.java

  • 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.util.ArrayList;
    import java.util.List;
    import java.util.UUID;
    @WebServlet(name = "LoginServlet", urlPatterns = "/LoginServlet")
    public class LoginServlet extends HttpServlet {
        public static List<User> data = null;
        public static User getData(String userId){
            for(int i=0; data!=null && i<data.size(); i++) {
                User user = data.get(i);
                if(user.getUserId().equalsIgnoreCase(userId)){
                    return user;
                }
            }
            return null;
        }
        @Override
        public void init() throws ServletException {
            super.init();
            data = new ArrayList<User>();
            for (int i = 0; i < 3; i++) {
                User user = new User();
                user.setUserId(UUID.randomUUID().toString());
                user.setUsername(i + "" + i);
                user.setPassword(i + "" + i);
                data.add(user);
            }
        }
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            for(int i=0; data!=null && i < data.size(); i++) {
                User user = data.get(i);
                if(user.getUsername().equalsIgnoreCase(username) && user.getPassword().equalsIgnoreCase(password)){
                    String loginTimeStr = request.getParameter("loginTime");
                    Integer loginTime = 0;
                    if (loginTimeStr != null) {
                        loginTime = Integer.parseInt(loginTimeStr);
                    }
                    Cookie cookie = new Cookie("autoLogin", user.getUserId());
                    cookie.setMaxAge(loginTime*24*60*60);
                    response.addCookie(cookie);
                    request.getSession().setAttribute("username", username);
                    request.getRequestDispatcher("login.jsp").forward(request, response);
                }
            }
            throw new RuntimeException("账号密码错误");
        }
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }

 AutoLoginFilter.java

  • import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    @WebFilter(filterName = "AutoLoginFilter", urlPatterns = "/*")
    public class AutoLoginFilter implements Filter {
       public void doFilter(ServletRequest req, ServletResponse resp,
             FilterChain chain) throws IOException, ServletException {
          
          HttpServletRequest request = (HttpServletRequest) req;
          HttpServletResponse response = (HttpServletResponse) resp;
          
          if(request.getSession().getAttribute("user")!=null){
             chain.doFilter(request, response);
             return;
          }
          String value = null;
          Cookie cookies[] = request.getCookies();
          for(int i=0; cookies!=null && i<cookies.length; i++){
             if(cookies[i].getName().equalsIgnoreCase("autoLogin")){
                value = cookies[i].getValue();
             }
          }
          if(value!=null){
             User user = LoginServlet.getData(value);
             if(user!=null)
                request.getSession().setAttribute("username", user.getUsername());
          }
          chain.doFilter(request, response);
       }
       
       public void destroy() {
          // TODO Auto-generated method stub
       }
       public void init(FilterConfig filterConfig) throws ServletException {
          // TODO Auto-generated method stub
       }
    }

login.jsp

  • <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Login</title>
    </head>
    <body>
        <div>
            <form action="${pageContext.request.contextPath}/LoginServlet" method="post">
                <p>帐号:<input type="text" name="username" /></p><br/>
                <p>密码:<input type="password" name="password" /></p><br/>
                <p>记住账号:
                    <input type="radio" name="loginTime" value="7" checked="checked" />一周
                    <input type="radio" name="loginTime" alue="3" />三天
                    <input type="radio" name="loginTime" value="0" />永不
                </p><br />
                <input type="submit"/>
            </form>
        </div>
        <label>${sessionScope.username}</label>
    </body>
    </html>

 

 

转载于:https://my.oschina.net/cnzxzc/blog/662060

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值