Cookie 与 Session
一. HTTP 无状态,无连接
- HTTP 无状态:不保留客户端与服务器之间的会话状态。每个请求都是独立的,服务器无法识别不同请求是否来自同一个客户端。(用户登录后访问另一个页面,服务器无法自动识别用户身份,除非通过 Cookie/Session 等机制手动维护)
- HTTP 无连接:在每次请求 - 响应完成后立即关闭 TCP 连接,下次请求需重新建立连接。(客户端请求一个 HTML 页面,服务器返回内容后断开连接。若页面包含多个资源(图片、CSS),每个资源都需单独建立连接)
实验:首先登入B站后,再启动一个网页登入B站,发现不再需要输入密码了?
问题:B 站是如何认识我这个登录用户的?HTTP 是无状态,无连接的,怎么能够记住我?
答案:HTTP 引入了 Cookie/Session (登入会话管理) 技术!
二. Cookie
1. Cookie 介绍
- 定义:Cookie 是存储在用户本地浏览器中的小段数据,由服务器通过 HTTP 协议发送给浏览器,浏览器会在后续请求中将这些数据回传给服务器。Cookie 通常用于会话管理、用户偏好设置、身份验证等。
工作原理:
- 服务器设置 Cookie:浏览器首次访问服务器时,服务器通过在 HTTP 响应头中添加 Set-Cookie 来设置 Cookie。
- 浏览器存储 Cookie:浏览器收到响应后,根据 Set-Cookie 的属性决定是否存储该 Cookie。
- 浏览器回传 Cookie:在后续请求中,浏览器会自动将符合条件的 Cookie 发送给服务器。
分类:
- 会话 Cookie:用户登录一个网站后,服务器设置一个会话 Cookie,用于在用户浏览网站期间保持登录状态。当用户关闭浏览器后,会话 Cookie 被删除,登录状态结束。储存在浏览器内存中。
- 持久 Cookie:用户选择“记住我”选项登录一个网站后,服务器设置一个持久 Cookie,用于在用户下次访问时自动登录。该 Cookie 会在用户设备上保留,直到过期时间到达或用户手动清除浏览器数据。储存在用户设备的磁盘。
如果 Cookie 是一个持久性的 Cookie,那么它其实就是浏览器相关的,特定目录下的一个文件。但直接查看这些文件可能会看到乱码或无法读取的内容,因为 Cookie 文件通常以二进制或 sqlite 格式存储。一般我们查看,直接在浏览器对应的选项中直接查看即可。类似于下面这种方式查看:
- 安全性:由于 Cookie 是存储在客户端的,因此存在被篡改或窃取的风险。
- 用途:用户认证和会话管理、跟踪用户行为、缓存用户偏好等。
2. Cookie 使用
两种Cookie相关的报头:
- HTTP 响应报头选项:Set-Cookie,可以用来进行给浏览器设置 Cookie 值。
- HTTP 请求报头选项:Cookie,客户端在后续请求中,通过 Cookie 请求头携带已存储的 Cookie。
1. Set-Cookie 格式
Set-Cookie: Cookie名称=Cookie内容; expires=Thu, 18 Dec 2024 12:00:00 UTC; path=/; domain=.bilibili.com; secure; HttpOnly
属性 | 值 | 描述 |
---|---|---|
Cookie 名称 | Cookie 内容 | 可以是username=zhangsan 或 passwd=123456 等等 |
expires | Thu, 18 Dec 2024 12:00:00 UTC | Cookie 将在 2024 年 12 月 18 日 12:00 UTC 过期 |
path | / | 在根目录下的所有请求都会携带该 Cookie |
domain | .bilibili.com | 指定哪些域名可以接收这个 Cookie,点前缀表示包括所有子域名 |
secure | 无 | 指示 Cookie 只能通过 HTTPS 协议发送,不能通过 HTTP 协议发送,增加安全性 |
HttpOnly | 无 | 只能被 HTTP 协议读取,阻止客户端脚本(JavaScript)访问此 Cookie,有助于防止跨站脚本攻击(XSS) |
2. Cookie 实验测试
1. 测试 Set-Cookie: 名称和内容 写入到浏览器
- 浏览器第一次请求服务器:发送请求成功后,返回响应报头 Set-Cookie: username=zhangsan 给浏览器!浏览器中存在 Cookie 文件(名称:username,内容:zhangsan,还有一些默认属性)
- 浏览器第二次请求服务器:发送请求成功后,服务器解析请求报头发现存在 Cookie: username=zhangsan!
2. 测试 Set-Cookie: expires 写入到浏览器
- 浏览器第一次请求服务器:发送请求成功后,返回响应报头 Set-Cookie: username=zhangsan; expires=Sat, 22 Mar 2025 14:59:14 UTC; 给浏览器!浏览器中存在 Cookie 文件(名称:username、内容:zhangsan、属性expires:该文件一分钟后过期,此时报头中不再存在 Cookie: username=zhangsan、还有一些默认属性)
- 浏览器第二次请求服务器:发送请求成功后,服务器解析请求报头发现存在 Cookie: username=zhangsan!请求报头 Cookie 只存在 Cookie名称=Cookie内容!
3. 测试 Set-Cookie: path 写入到浏览器
- 浏览器第一次请求服务器:发送请求成功后,返回响应报头 Set-Cookie: username=zhangsan; path=/a/b; 给浏览器!浏览器中存在 Cookie 文件(名称:username、内容:zhangsan、属性path:只有请求 /a/b 路径下的资源,报头中才存在 Cookie: username=zhangsan、还有一些默认属性)
- 浏览器第二次请求服务器:发送请求成功后,服务器解析请求报头发现存在 Cookie: username=zhangsan!注意:请求报头 Cookie 只存在 Cookie名称=Cookie内容!
4. 测试两组 Set-Cookie 写入到浏览器
- 浏览器第一次请求服务器:发送请求成功后,返回响应报头 Set-Cookie: username=zhangsan; path=/a/b; 和 Set-Cookie: passwd=1234567890; path=/a/b; 给浏览器!浏览器中存在两个 Cookie 文件:username 和 passwd!
- 浏览器第二次请求服务器:发送请求成功后,服务器解析请求报头发现存在 Cookie: username=zhangsan; passwd=1234567890!
3. Cookie 泄漏问题
- 我们写入的是测试数据,如果写入的是用户的私密数据呢?比如,用户名密码,浏览痕迹等。
- 本质问题在于这些用户私密数据在浏览器(用户端)保存,非常容易被人盗取,更重要的是,除了被盗取,还有就是用户私密数据也就泄漏了,需要引入 Session!
- 例如:我是一个黑客,我将你的 QQ 的 Cookie 文件信息盗取了,将其放在 QQ 所在的路径下,我不需要 QQ 密码,就可以直接登入你的 QQ!
三. Session
Cookie 是存在客户端中的,而 Session 是存在服务器中的!
1. Session 介绍
- 定义:HTTP Session 是服务器用来跟踪用户与服务器交互期间用户状态的机制。由于 HTTP 协议是无状态的(每个请求都是独立的),因此服务器需要通过 Session 来记住用户的信息。
工作原理:
- 服务器设置 Cookie:浏览器首次访问服务器时,服务器会为用户创建一个唯一的 Session ID,并通过 Set-Cookie 发送到客户端。
- 浏览器回传 Cookie:客户端在之后的请求中会携带这个 Session ID,服务器通过 Session ID 来识别用户,从而获取用户的会话信息。
- 服务器通常会将 Session 信息存储在内存、数据库或缓存中。
安全性:
- 由于 Session ID 是在客户端和服务器之间传递的,因此也存在被窃取的风险。
- 但是用户只泄漏了一个 Session ID,私密信息暂时没有被泄露的风险。
- Session ID 便于服务端进行客户端有效性的管理,比如异地登录。
- 可以通过 HTTPS 和设置合适的 Cookie 属性(如 HttpOnly 和 Secure)来增强安全性。
- 超时和失效:Session 可以设置超时时间,当超过这个时间后,Session 会自动失效。服务器也可以主动使 Session 失效,例如当用户登出时。
- 用途:用户认证和会话管理、存储用户的临时数据(如购物车内容)、实现分布式系统的会话共享(通过将会话数据存储在共享数据库或缓存中)
2. Session 使用
Set-Cookie: sessionid=123456;
四. 总结
- HTTP Cookie 和 Session 都是用于在 Web 应用中跟踪用户状态的机制。Cookie 是存储在客户端的,而 Session 是存储在服务器端的。它们各有优缺点,通常在实际应用中会结合使用,以达到最佳的用户体验和安全性。