当前位置: 首页 > article >正文

Cookie与Session详解

Cookie简介

Cookie 是浏览器提供的持久化存储数据的一种机制。是指某些网站为了辨别用户身份进行会话跟踪储存在用户本地终端上的数据(通常经过加密)。以下是关于 Cookie 的详细介绍:

Cookie工作原理

当你访问一个网站时,该网站的服务器会向你的浏览器发送一个小的文本文件,即 Cookie。浏览器会将这个 Cookie 存储在你的设备上。在你下次访问同一网站时,浏览器会将存储的 Cookie 发送回该网站的服务器,服务器可以通过 Cookie 中的信息来识别你的身份、记录你的偏好设置或跟踪你的浏览行为等。


具体的工作流程:
1.设置 Cookie:当用户第一次访问某个网站时,在服务器端,可以通过在 HTTP 响应头中设置 “Set-Cookie” 字段来设置 Cookie。并发送给浏览器。浏览器将 Cookie 存储在本地。

2.读取 Cookie:在后续对该网站的请求中,浏览器会自动在请求头中携带该网站的 Cookie,服务器可以通过读取 Cookie 来获取用户的相关信息。

举例说明:如用户登录后,服务器设置一个包含用户身份信息的 Cookie,这样用户在访问其他页面时,服务器可以通过这个 Cookie 识别用户已登录状态,无需再次登录。

如图所示:

解释说明:

第一步:当我通过浏览器向淘宝这个网站发起请求时,淘宝服务器就会给我返回一个淘宝页面 。

第二步:在第一步返回的淘宝页面中,浏览器发起登录请求,此时服务器响应,服务器会去查询数据库,去校验用户名和密码是否正确,如果正确,登录成功,并且通过SetCookie字段设置身份序号。浏览器收到服务器响应之后,把身份序号保存到Cookie中。

第三步:服务器会把当前用户的身份信息在内存中也保存一份,同时给当前用户分配一个表示身份序号,这个序号是唯一的。这个就叫SessionID。服务器使用像hash表这样的数据结构把序号作为key,身份信息作为value存储起来,服务器生成的这些键值对称为Session(会话)。在后续请求中服务器收到Cookie中的身份序号,就会查询hash表,判定用户是谁,如果查询到了就知道用户是谁了,避免了重复输入账号和密码。如果没有查询到,就会要求用户重新进行登录操作。

Cookie作用

1.用户登录状态:当你登录一个网站后,网站可以通过 Cookie 记住你的登录状态,这样你在浏览该网站的其他页面时无需再次输入用户名和密码。

2.个性化体验:网站可以利用 Cookie 记住你的偏好设置,如语言选择、字体大小、页面布局等,为你提供更加个性化的浏览体验。

3.购物车功能:在电子商务网站中,Cookie 用于跟踪你添加到购物车中的商品,确保在你浏览不同页面或离开网站后再次返回时,购物车中的商品仍然存在。

4广告定向:广告商可以利用 Cookie 跟踪你的浏览行为,以便向你展示更加相关的广告。例如,如果你最近浏览了一些体育用品网站,你可能会在其他网站上看到与体育用品相关的广告。

Cookie安全问题

Cookie 可能被窃取,例如通过网络监听、跨站脚本攻击等;Cookie 可能被篡改,导致用户信息被伪造。


防范措施:
1.使用 HTTPS 加密连接,防止 Cookie 在传输过程中被窃取。设置 HttpOnly 属性,防止 JavaScript 脚本访问 Cookie。

2.对 Cookie 的值进行加密,增加安全性;定期清理过期的 Cookie,减少安全风险。
 

Session简介

session(会话)是一种用于跟踪用户与服务器之间交互状态的机制。

Session的作用

  1. 状态保持:HTTP 协议是无状态的,这意味着每个请求都是独立的,服务器无法直接知道不同请求是否来自同一个用户。Session 机制允许服务器在多个请求之间识别和跟踪特定的用户,从而实现状态保持。例如:当用户登录到一个网站后,服务器可以创建一个 session,并在后续的请求中通过 session ID 识别该用户,确保用户在不同页面浏览或进行操作时仍然保持登录状态。

  2. 存储用户相关信息:Session 可以存储特定于用户的信息,如用户的登录状态、权限级别、购物车内容等。例如:在一个电子商务网站中,用户将商品添加到购物车后,购物车的信息可以存储在 session 中,以便在用户浏览不同页面时仍然可以访问购物车中的商品。

Session工作原理

  1. Session ID 的生成和传递

    • 当用户首次访问服务器时,服务器会创建一个唯一的 session ID。这个 ID 可以通过多种方式传递给客户端,最常见的方式是使用 cookie。服务器将 session ID 存储在一个名为 '' JSESSIONID ''的 cookie 中,并发送给客户端。
    • 客户端在后续的请求中会自动将这个 cookie 发送回服务器,服务器通过读取 session ID 来识别对应的 session。
  2. Session 的存储和管理

    • 服务器通常将 session 数据存储在内存中,或者使用数据库、文件系统等外部存储来持久化 session 数据。不同的 Web 应用服务器和框架有不同的 session 管理方式。
    • 例如: Servlet 规范中,服务器可以使用HttpSession接口来管理 session。开发人员可以通过request.getSession()方法获取当前用户的 session 对象,并在其中存储和读取数据。

优势和注意事项

  1. 优势

    • 提供了一种方便的方式来管理用户状态,使得开发人员可以更轻松地构建复杂的 Web 应用。
    • 相对于将用户状态存储在客户端(如使用 cookie 存储大量数据),session 更加安全,因为用户无法直接修改服务器端存储的 session 数据。
  2. 注意事项

    • 由于 session 数据存储在服务器端,因此如果有大量的用户同时访问,可能会占用较多的服务器内存。需要合理管理 session 的大小和生命周期,及时清理过期的 session。
    • 如果服务器集群部署,需要考虑 session 的共享和同步问题,以确保用户在不同服务器之间的请求能够正确地识别和使用同一个 session。

实现登录功能来理解Cookie和Session

流程:

1.点击一个登录按钮,触发一个登录请求。

2.验证用户名,密码是否正确,如果正确(登录成功)跳转到主页面,如果不正确(登录失败)跳转到登录页面。

前端登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
  <form action="login" method="post">
    <input type="text" name="username">
    <br>
    <input type="password" name="password">
    <br>
    <input type="submit" value="提交">
  </form>
</body>
</html>

登录校验

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 验证用户名密码是否正确.
        // 正常情况下, 用户名密码会使用数据库来保存.
        // 此处直接写死.
        // 此处约定, 用户名合法的是 zhangsan 和 lisi
        // 密码合法的都是 123

        if (!username.equals("zhangsan") && !username.equals("lisi")) {
            // 登陆失败!!
            // 重定向到 登陆页面
            System.out.println("登陆失败, 用户名错误!");
            resp.sendRedirect("login.html");
            return;
        }
        if (!password.equals("123")) {
            // 登陆失败!!
            System.out.println("登陆失败, 密码错误!");
            resp.sendRedirect("login.html");
            return;
        }
        // 登陆成功
        // 1. 创建一个会话.
        HttpSession session = req.getSession(true);
        // 2. 把当前的用户名保存到会话中. 此处 HttpSession 又可以当成一个 map 使用.
        session.setAttribute("username", username);
        // 3. 重定向到主页
        resp.sendRedirect("index");
    }
}

主页面


import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    // 通过 重定向, 浏览器发起的是 GET .
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 先判定用户的登陆状态.
        // 如果用户还没登陆, 要求先登陆.
        // 已经登陆了, 则根据 会话 中的用户名, 来显示到页面上.
        // 这个操作不会触发会话的创建.
        HttpSession session = req.getSession(false);
        if (session == null) {
            // 未登录状态
            System.out.println("用户未登录!");
            resp.sendRedirect("login.html");
            return;
        }
        // 已经登陆
        String username = (String) session.getAttribute("username");
        // 构造页面.
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("欢迎 " + username + "回来!");
    }
}

运行结果:

   // 1. 创建一个会话.
        HttpSession session = req.getSession(true);

 解释说明:

会话是一个键值对,key是sessionId,value是一个HttpSession对象,每个客户端进行登录的时候都有一个这样的会话(键值对),服务器要管理多个这样的键值对(会话),服务器采用像哈希表这样的数据结构,把这些键值对(会话)存储起来。

创建会话的过程:

1.构造一个HttpSession对象。

2.构造唯一的sessionId。

3. 把这个键值对插入哈希表中。

4.把sessionId设置到响应报文,Set-Cookie中。

req.getSession(true)的意思:判定当前请求是否已经有对应的会话了,(拿着请求中Cookie里的SessionId查一下哈希表),如果sessionId不存在,或者没有查到,就会创建新会话,并插入到哈希表当中,如果查到了,直接返回查到的结果。

    // 1. 创建一个会话.
        HttpSession session = req.getSession(true);
        // 2. 把当前的用户名保存到会话中. 此处 HttpSession 又可以当成一个 map 使用.
        session.setAttribute("username", username);

用一个简图来说明服务器是如何组织会话的,如下图所示:

注意:HttpSession对象自己也是一个键值对,用setAttribute,getAttribute 来存取键值对,这里的键值对是开发者自定义的数据。

抓包工具查看交互过程

Cookie 和Session的关联和区别

关联:在网站的登录功能中,需要配合使用。

区别:

1.Cookie是客户端的存储机制,Session是服务器的存储机制。

2.Cookie里面可以存放各种键值对,Session专门用来保存用户的身份信息。

3.Cookie可以单独使用,不搭配Session(实现非登录场景下)。

4.Session也可以单独使用,不搭配Cookie(比如:手机app登录服务器,,服务器需要Session,此时没有Cookie的概念了,Cookie是跟浏览器强相关的)。

5.Cookie是HTTP协议中的一部分,Session则可以和HTTP无关,(比如TCP,websocket也可以使用Session)。

一、存储位置

  • Session:数据存储在服务器端。服务器为每个会话创建一个唯一的 Session ID,并将相关数据与这个 ID 关联起来存储在服务器的内存或其他存储介质中。
  • Cookie:数据存储在客户端,即在用户的浏览器中。Cookie 是一小段文本信息,由服务器发送给客户端并由客户端保存。

二、安全性

  • Session:相对更安全,因为用户无法直接访问和修改服务器端存储的 Session 数据。服务器可以对 Session 数据进行加密和严格的访问控制。
  • Cookie:存储在客户端,容易被用户篡改或窃取。虽然可以对 Cookie 进行加密,但仍然存在一定的安全风险。

三、存储容量

  • Session:通常没有严格的容量限制,因为存储在服务器端,可以根据服务器的资源进行调整。但如果存储过多数据可能会占用较多服务器内存。
  • Cookie:有大小限制,不同浏览器对 Cookie 的大小限制略有不同,一般在 4KB 左右。

四、生命周期

  • Session:其生命周期通常由服务器控制。可以通过设置超时时间来决定 Session 的有效期。当用户长时间没有活动时,服务器可能会自动销毁 Session。
  • Cookie:可以设置不同的生命周期。可以是会话级别的(在浏览器关闭时自动删除),也可以设置一个特定的过期时间,在过期时间到达之前,Cookie 会一直存在于客户端。

五、跨域访问

  • Session:一般情况下,Session 在同一应用服务器内的不同页面之间共享比较容易,但在跨域场景下需要进行额外的配置和处理。
  • Cookie:可以通过设置domainpath属性来控制在不同域和路径下的访问权限,相对来说在一些跨域场景下更容易进行配置。

六、对性能的影响

  • Session:由于数据存储在服务器端,大量的 Session 可能会占用服务器内存,影响服务器性能。特别是在高并发场景下,需要合理管理 Session 的数量和大小。
  • Cookie:存储在客户端,对服务器性能影响较小。但如果存储过多或过大的 Cookie,可能会影响客户端的性能,尤其是在每次请求都需要发送 Cookie 的情况下。


http://www.kler.cn/a/588957.html

相关文章:

  • QuickAPI 和 DBAPI 谁更香?SQL生成API工具的硬核对比(一)
  • 从零实现区块链共识算法:用Python解锁去中心化世界的关键
  • 企业管理杂谈:产品经理的选拔和培养——企业产品创新发展的关键
  • Python核心语法-数据基本运算(一)
  • 玩转python:通俗易懂掌握高级数据结构:collections模块之defaultdict
  • Android第二次面试总结(项目拷打实战)
  • 线性代数(1)用 excel 计算鸡兔同笼
  • 0CTF 2016 piapiapia 1
  • Kafka的流量控制机制
  • 玩转python:通俗易懂掌握高级数据结构-collections模块之UserList
  • AI大语言模型LLM学习-基于Vue3的AI问答页面
  • 深入解析前后端分离架构:原理、实践与最佳方案
  • [IP]RGMII
  • 通过deepseek学习lua写网页
  • 人工智能与机器学习——系统学习规划
  • 鸿蒙应用开发—ZDbUtil高效使用数据库
  • 82.HarmonyOS NEXT 性能优化指南:从理论到实践
  • 【大模型】Transformer、GPT1、GPT2、GPT3、BERT 的论文解析
  • 【RabbitMQ】rabbitmq在spring boot中的使用
  • 交互式可视化进阶(Plotly Dash构建疫情仪表盘)