【会话技术】Cookie和Session的工作流程、区别及如何使用

Cookie技术

web程序是通过HTTP协议传输的,而HTTP是一个无状态的协议,当一个客户端向服务器发送请求,在服务器返回响应后,连接就关闭了,在服务器器端不保留连接信息。当客户端发送多次请求且需要相同的请求参数的时候,就还需要重传。这样如果数据量很大的情况下,效率就会大打折扣。Cookie的出现就是为了解决这个问题。

Cookie的工作流程:

客户端第一次请求时携带数据发送给服务器,服务器这边决定将哪个数据用Cookie存储,并通过响应将Cookie存在响应报文中的header中返回给客户端,然后客户端这边会存储在浏览器上或硬盘中。之后每次HTTP请求中自动携带这个Cookie给服务器。它位于header中的一个属性,键值对结构。

Cookie的缺点:

数量有限,单个存储大小有限,安全性无法得到保障,浏览器可以禁用cookie。如果用户禁用cookie,则无法使用cookie。

Cookie的生存周期:

可以根据需求设置。分为临时Cookie和持久化Cookie,临时Cookie时=是储存在内存中的,当浏览器关闭的时侯,Cookie自动失效。持久化Cookie是保存在浏览器中的某个存储目录,当时间过期之后才会失效。有些页面将Cookie的生存周期设置为0或者负值,这样在关闭浏览器时,就会马上消除Cookie,不会记录用户的信息,更加安全。上述失效指的都是浏览器这边删除了Cookie。

Cookie的应用场景:

对于安全性不高的数据,数据量不大的数据存储比较合适。可以用来处理客户端发送不同请求的时候如何使用相同的参数信息。

cookie可以用来保存用户的登录信息。比如10天内免登陆等等。如果删除cookie下次就需要重新登陆。

Cookie练习:实现一周内免登录。

  • 1.登录前端页面代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="login" method="post">
        <div class="row">
            用户名
            <input type="text" name="username">
        </div>
        <div class="row">
            密码
            <input type="password" name="password">
        </div>
        <div class="row">
            <input type="checkbox" id="checkbox" name="memory" value="true" checked="checked">一周内免登陆
        </div>
        <div class="row">
            <input type="submit" value="登录">
        </div>
    </form>

    <script src="js/jquery.js"></script>
    <script>
        function show(){
            $.ajax({
                type: 'get',
                url: 'cookie',
                success: function (data,status,xhr) {
                    if(xhr.status==278){
                        console.log(data)
                        window.location.href=data.url;
                    }
                }
            });
        }
        show()
    </script>

</body>
</html>
  • 2.主页面代码 :
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>登陆成功</h1>
</body>
</html>
  • 3.后端登录操作代码:
// 登录操作
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String memory = req.getParameter("memory");
        //先判断输入是否完整
        if(username==null || password==null || "".equals(username) || "".equals(password)) {
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("用户名或密码不能为空");
            return;
        }

        //再判断是否存在该用户 去数据库中查找 这里省略 默认存在

        //再判断用户有没有点击免登录操作
        if(Boolean.valueOf(memory)) {
            //说明点击了免登录操作,就要进行创建Cookie对象
            //创建Cookie对象
            Cookie cookie1 = new Cookie("username",username);
            Cookie cookie2 = new Cookie("password",password);
            //设置有效访问路径
            cookie1.setPath("/");
            cookie2.setPath("/");
            //设置Cookie时间 单位秒
            cookie1.setMaxAge(7*24*3600);
            cookie2.setMaxAge(7*24*3600);
            //向客户端返回Cookie信息
            resp.addCookie(cookie1);
            resp.addCookie(cookie2);

        }
        //跳转到主页面
        resp.sendRedirect("main.html");
    }
}
  • 4.访问登录页面时检验cookie代码: 
//每次访问登录页面时,前端ajax都会向这段代码(后端)发送请求 
//检验是否有cookie
@WebServlet("/cookie")
public class CookieServlet extends HttpServlet {
    private ObjectMapper mapper= new ObjectMapper();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //先获取Cookie
        Cookie[] cookies = req.getCookies();
//        if(cookies==null) {
//            return;
//        }
        if(cookies!=null && cookies.length>0) {
            //说明请求中有Cookie
            for (Cookie cookie : cookies) {
                //获取用户名
                if("username".equals(cookie.getName())) {
                    String username = cookie.getValue();
                }
                //获取密码
                if("password".equals(cookie.getName())) {
                    String password = cookie.getValue();
                }
            }

            //在数据库中进行匹配 这里逻辑由自己编写 默认匹配成功

            //重定向到主页面
            Demo demo = new Demo("main.html");
            resp.setStatus(278);
            resp.setContentType("application/json");
            resp.getWriter().write(mapper.writeValueAsString(demo));
        }else {
            resp.setContentType("text/html;charset=utf8");
            resp.sendRedirect("login.html");

        }
    }
}

Session技术

会话:用户打开一个浏览器,点击多个超链接,访问服务器多个web资源然后关闭浏览器,整个过程称之为一个会话。

Session的工作流程:

  • 当用户请求应用程序的web页面时,如果该用户还没有会话,就会为该用户创建一个会话,即创建一个Session对象,该对象中会存储该用户会话所需的一些信息。
  • 这样,当用户在应用程序的多个web页面进行跳转时,存储在session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去,存储在这个对象里的数据在多个页面数据共享。
  • 会话创建成功后,服务器这边生成一个sessionId和一个HttpSession对象,该对象中就有该用户的一些信息。并且这个sessionId服务器会发送给客户端,同时服务器这边也会把sessionId和对应的用户信息,用户操作记录在服务器上以哈希表结构存储(类似于键值对里套了个键值对,见下图),客户端收到sessionId后会储存在cookie里,再次访问时就会携带这个存有sessionId的Cookie,服务器通过sessionId就知道用户是谁了。类似于去理发店剪头发,店员就会让你办一个会员卡,办了之后,理发店就会有你的一些相关信息,比如姓名,电话号码,消费记录,余额等。并且会给你一个会员卡(相当于sessionId),下次理发时拿上会员卡,理发店就知道是哪位顾客来了。

假设一个网站对应一个 webapp, 而 webapp 必然储存着大量用户的会话 Session, 存储的结构是类哈希表结构, 一个会话的Key 值是 服务器分配的 id, 即 sessionId, 这个Key对应的value(HttpSession)是这个用户的个人信息, 也是以键值对的形式组织的。

最外面的两个sessionId和HttpSession是以键值对形式存储在哈希表上。其中sessionId作为一个键存在,HttpSession对象本身作为一个值存在,而HttpSession对象里面的一些属性又是以键值对形式存储。即就是键值对的值里又套了一个键值对。

Session的生命周期:

可以根据需求设置。默认是30分钟。举个例子,如果设为10分钟的话,当你登录一个服务器,登陆成功的话,服务器会返回一个sessionId,登陆成功之后的10分钟内没有客户端这边进行任何HTTP请求,10分钟后你再发送一个HTTP请求,就会提示你需要重新登陆。

每次登陆的时候会重新创建会话,服务器重新返回sessionId,客户端通过请求中携带的id可以不断访问该web程序的多个界面,生命周期结束有常见的两种,用户主动点击退出登录(注销)或一段时间内没有进行操作。后面用户再次登录时就需要重新登陆,重新创建会话以及服务器返回新的sessionId。以此循环。注销就是服务器那边通过代码逻辑消除了会话对象。id也消除了。客户端这边再次请求时id就会无法匹配,就需要重新登陆。一段时间内不操作也是如此。

Session的应用场景:

判断一个用户是否是登录状态,非登录状态强制跳转到登录页面。不是所有用户都会先进入登录页面输密码,有可能他直接在地址栏里强行输入主界面或其他操作界面的URL,这个时候就会出现问题。我们可以使用Session,当用户登录的时候为他设置一个session对象,直至退出登录,该session销毁。并在每个页面里加入判断是否存在session对象,不存在就强制跳转到登录页面。

进一步想要提高安全性,可以对sessionId增加时间和空间上的显示,异地需重新登录,一段时间后需要重新登陆。

代码示例,登录时创建会话: 

        // 验证通过 进行登录 创建会话 使用该会话创建用户信息
        // true表示会话存在就查找 不存在就创建新的会话
        HttpSession session = req.getSession(true);
        // 会话保存操作  后续通过第一个参数获取到会话 
        session.setAttribute("user",user);
        // 进行重定向 跳转到主页面 重定向使得登录成功操作不能去回转
        resp.sendRedirect("mainInterface.html");

 代码示例,获取会话:

        // 使用这个方法来获取用户的状态
        // false的作用 有会话返回对象 无会话则返回null
        HttpSession session = req.getSession(false); 
        if(session == null) {
            //说明无会话 表明该用户是未登录状态
            //创建一个空的用户对象
            User user = new User();
            //将空对象的内容以json格式进行响应
            String respJson = mapper.writeValueAsString(user);
            resp.getWriter().write(respJson);
            return;
        }

        //获取会话对象
        User user = (User) session.getAttribute("user");//与上面保存会话的key值要一样


两者区别:

  • 存储位置不同

Cookie可以存储在浏览器或本地硬盘上,Session只能存储在服务器上。

  • 安全性不同

Session比Cookie更安全。

  • 对服务器的压力不同

Session占用服务器资源和性能,Session过多,会增加服务器压力。

  • 存储大小不同

Cookie在浏览器这边存储,浏览器对cookie的存储有限制,个数一般不超过20个,单个Cookie存储的数据不超过4k。Session没有大小限制,它与服务器的内存大小有关。

  • 存储对象不同

Session能存储任意类型的Java对象(类似于哈希表结构存储),Cookie只能存储String类型的对象。(以键值对结构存储)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

去北极避暑~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值