HTTP 是一种无状态协议,这意味着服务器在处理完客户端的请求后,不会保留关于该请求的任何信息。然而,在实际的 Web 应用中,我们常常需要记住用户的状态(例如登录状态、购物车内容等)。为了实现这一点,引入了 Cookie 和 Session 机制。
一、Cookie
1. 什么是 Cookie
HTTP Cookie(也称为Web Cookie、浏览器Cookie 或简称Cookie) 是服务器发送到用户浏览器并保存在本地的一小段数据(通常经过加密)。浏览器会存储这些数据,并在下次向同一服务器发送请求时,将它们附加在请求头中发送给服务器。通过这种方式,服务器可以识别出不同的客户端。
○HTTP 存在一个报头选项:Set-Cookie, 可以用来进行给浏览器设置Cookie值。
○在HTTP 响应头中添加,客户端(如浏览器)获取并自行设置并保存Cookie。
基本格式
cpp
Set-Cookie: <name>=<value>
其中<name> 是Cookie 的名称,<value> 是Cookie 的值。
完整的Set-Cookie 示例
cpp
Set-Cookie: username=peter; expires=Thu, 18 Dec 2024 12:00:00
UTC; path=/; domain=.example.com; secure; HttpOnly
时间格式必须遵守RFC 1123 标准,具体格式样例:Tue, 01 Jan 2030 12:34:56GMT 或者UTC(推荐)。
关于时间解释
- Tue: 星期二(星期几的缩写)
- ,: 逗号分隔符
- 01: 日期(两位数表示)
- Jan: 一月(月份的缩写)
- 2030: 年份(四位数)
- 12:34:56: 时间(小时、分钟、秒)
- GMT: 格林威治标准时间(时区缩写)
2. Cookie 的结构与属性
一个 Cookie 通常包含以下属性:
- 名称(Name) 和 值(Value):唯一标识 Cookie 并携带数据。
- 域(Domain):指定哪些主机可以接受该 Cookie。例如设置为.example.com,则所有子域都可接收。
- 路径(Path):指定 URL 路径,只有匹配该路径的请求才会携带 Cookie。
- 过期时间(Expires/Max-Age):决定 Cookie 的生命周期。
○会话Cookie(Session Cookie):在浏览器关闭时失效。
○持久Cookie(Persistent Cookie):带有明确的过期日期或持续时间,可以跨多个浏览器会话存在。
○如果设置了expires 属性,则Cookie 将在指定的日期/时间后过期。
○如果没有设置expires 属性,则Cookie 默认为会话Cookie,即当浏览器关闭时过期
○如果cookie 是一个持久性的cookie,那么它其实就是浏览器相关的,特定目录下的一个文件。但直接查看这些文件可能会看到乱码或无法读取的内容,因为cookie 文件通常以二进制或sqlite 格式存储。一般我们查看,直接在浏览器对应的选项中直接查看即可。
类似于下面这种方式:

- 安全标志(Secure):如果设置,Cookie 只在 HTTPS 连接中传输。
- HttpOnly:如果设置,JavaScript 无法通过document.cookie访问该 Cookie,有助于防止 XSS 攻击。
- SameSite:控制跨站请求时是否发送 Cookie,用于防范 CSRF 攻击(取值:Strict、Lax、None)。
以下是对Set-Cookie 头部字段的简洁介绍

注意事项
○每个Cookie 属性都以分号(;)和空格( )分隔。
○名称和值之间使用等号(=)分隔。
○如果Cookie 的名称或值包含特殊字符(如空格、分号、逗号等),则需要
进行URL 编码。
3. Cookie 的工作原理
- 客户端首次访问服务器时,服务器在响应头中添加 Set-Cookie 字段。
- 浏览器收到响应后,根据 Set-Cookie 的指令存储 Cookie。
- 下次浏览器向同一服务器发送请求时,会自动在请求头中附加 Cookie 字段,携带所有符合条件(域、路径、过期时间等)的 Cookie。
- 服务器通过解析请求头中的 Cookie 来识别用户或获取状态信息
4. Cookie 的主要用途
- 会话管理:如用户登录状态、购物车信息(最重要)。
- 个性化设置:如语言偏好、主题颜色。
- 用户跟踪:用于分析用户行为(可能涉及隐私问题)。
5. Cookie 的限制
- 大小限制:大多数浏览器限制每个 Cookie 大小不超过 4KB。
- 数量限制:每个域名下的 Cookie 数量也有限制(通常为 20~50 个)。
- 安全性问题:Cookie 存储在客户端,易被篡改或窃取,因此不应存放敏感信息(如密码、信用卡号)。
二、Session
1. 什么是 Session
Session 是一种在服务器端保存用户状态信息的机制。当用户访问服务器时,服务器会为该用户创建一个唯一的会话(Session),并分配一个会话标识符(Session ID)。这个 Session ID 通常通过 Cookie 传递给客户端,客户端在后续请求中携带它,服务器根据 Session ID 找到对应的会话数据。
2. 为什么需要 Session
Cookie 存储在客户端,存在以下问题:
- 数据容易被篡改。
- 容量有限。
- 不适合存储敏感数据。
而 Session 将数据保存在服务器端,客户端只保存一个无意义的 ID,安全性更高,且存储容量几乎不受限制。
3. Session 的工作原理
- 客户端首次请求服务器时,服务器生成一个唯一的 Session ID,并在服务器内存(或数据库、文件等)中创建对应的 Session 数据结构,存储用户相关信息。
- 服务器通过响应头中的 Set-Cookie 将 Session ID 发送给客户端(通常 Cookie 名为 JSESSIONID 或 PHPSESSID 等)。
- 客户端收到后保存该 Cookie,后续请求中自动携带此 Cookie。
- 服务器从请求中提取 Session ID,查找对应的 Session 数据,从而识别用户状态。
- 当用户注销或 Session 过期时,服务器销毁 Session 数据。
4. Session 的存储方式
- 内存存储:默认方式,速度快,但服务器重启后数据丢失,不适合分布式环境。
- 文件存储:将 Session 数据写入文件,可持久化。
- 数据库存储:如 MySQL、Redis 等,适合分布式集群,共享 Session 数据。
- 缓存系统:如 Memcached、Redis,兼顾速度和共享。
5. Session 的生命周期
- 创建:通常在用户首次访问或执行登录操作时创建。
- 活跃:每次请求都会刷新 Session 的过期时间(取决于配置)。
- 失效 :
- 超时:服务器设置 Session 超时时间,超过时间未活动则自动销毁。
- 主动销毁:用户注销时调用session_destroy()或类似方法。
- 服务器重启(内存存储情况下)。
6.用途:
用户认证和会话管理
存储用户的临时数据(如购物车内容)
实现分布式系统的会话共享(通过将会话数据存储在共享数据库或缓存中)
三、Cookie 与 Session 的区别

四、安全注意事项
1. Cookie 安全
• 由于Cookie 是存储在客户端的,因此存在被篡改或窃取的风险。
- HttpOnly:防止 XSS 攻击窃取 Cookie。
- Secure:确保 Cookie 只在 HTTPS 上传输,避免中间人攻击。
- SameSite:设置为 Strict 或 Lax 可防御 CSRF 攻击。
- 签名/加密:对于敏感数据,应对 Cookie 值进行签名或加密,防止篡改。
2. Session 安全
- Session ID 强度:应生成足够随机且复杂的 ID,避免被猜测。
- 会话固定攻击:用户登录前分配 Session ID,登录后应重新生成 Session ID,防止攻击者使用已知 ID 劫持会话。
- 超时机制:设置合理的超时时间,避免会话长期有效。
- HTTPS 传输:确保 Session ID 在传输过程中加密,防止嗅探。
- 跨站请求伪造(CSRF):使用 Token 验证或 SameSite Cookie 防护。
3. 分布式环境下的 Session 管理
在集群或多服务器环境下,传统的服务器内存 Session 无法共享,常见的解决方案有:
- Session 复制:服务器之间同步 Session 数据(如 Tomcat 的集群会话复制),但开销大。
- 集中式存储:使用 Redis、Memcached 等外部存储统一管理 Session,所有服务器共享。
- 客户端存储:将 Session 数据加密后存储在 Cookie 中(如 JWT),但需考虑大小和安全性。
五、实际应用示例:用户登录流程
- 用户访问登录页面,输入用户名密码提交。
- 服务器验证身份成功后,创建一个 Session 对象,存储用户 ID 等信息,并生成唯一的 Session ID。
- 服务器在响应头中设置 CookieSet-Cookie: SESSIONID=xxxxxx; Path=/; HttpOnly; Secure
- 浏览器保存该 Cookie,后续请求自动携带。
- 用户访问其他页面时,服务器从请求中提取 Session ID,找到对应的 Session,确认用户已登录。
- 用户点击注销,服务器销毁 Session,并通知浏览器清除对应的 Cookie(通过设置过期时间为过去)。
六、总结
- Cookie 和 Session 共同解决了 HTTP 无状态的问题,但各有侧重。
- Cookie 适合存储少量、非敏感的数据,实现客户端状态的保持。
- Session 将状态信息保存在服务器端,更安全、容量更大,但需要配合 Cookie 或 URL 重写来传递标识符。
- 在实际开发中,应根据数据敏感性、存储需求、性能要求等因素合理选择,并注意安全配置,防止常见的 Web 漏洞。