Cookie 概述
HTTP Cookie(简称 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据。它会在浏览器之后向同一服务器再次发起请求时被携带并发送回服务器。通常,它用于告知服务端两个请求是否来自同一浏览器,比如保持用户的登录状态、记录用户偏好等。
Cookie 的原意是曲奇饼干,在网络语境下对应着一小块数据。理解它的核心在于明白它是客户端存储机制。
工作原理
- 设置:当用户第一次访问网站时,服务器会在响应的 HTTP 头中设置
Set-Cookie字段,将 Cookie 发送给浏览器。 - 存储:浏览器接收到 Cookie 后,会将其保存在本地(通常是按照域名进行存储)。
- 携带:在之后的请求中,浏览器会自动在 HTTP 请求头中携带
Cookie字段,将之前保存的 Cookie 信息发送给服务器。
有了 Cookie 的存在,我们不用每次登录都要输入账号密码,网站能自动识别用户。因为将用户的数据存储在了 Cookie 当中,它可以标识用户状态,对登录状态进行保持,方便随时验证身份,还能区分 VIP 会员、普通会员还是游客。
Cookie 的分类
- 会话 Cookie(Session Cookie):存储在内存当中,浏览器关闭时失效。
- 持久 Cookie(Persistent Cookie):存储在文件当中,带有明确的过期日期或持续时间,可以跨多个浏览器会话存在。
如果 Cookie 是持久性的,它实际上是浏览器相关目录下的一个文件。但直接查看这些文件可能会看到乱码或无法读取的内容,因为 Cookie 文件通常以二进制或 SQLite 格式存储。一般建议直接在浏览器的开发者工具或设置选项中查看。
安全性与用途
由于 Cookie 是存储在客户端的,因此存在被篡改或窃取的风险。不过,通过合理配置属性,风险可控。
主要用途包括:
- 用户认证和会话管理(最重要)
- 跟踪用户行为
- 缓存用户偏好等
Cookie 详解
基本格式
HTTP 响应头中包含 Set-Cookie 选项,用来给浏览器设置 Cookie 值。
Set-Cookie: =
其中 <name> 是 Cookie 的名称,<value> 是 Cookie 的值。
完整的 Set-Cookie 示例如下:
Set-Cookie: username=peter; expires=Thu, 18 Dec 2024 12:00:00 UTC; path=/; domain=.example.com; secure; HttpOnly
各个属性的含义:
- name=value:指定 Cookie 的名称和值,这是必需的。
- expires=date:指定 Cookie 的过期时间。如果未设置,Cookie 默认在浏览器关闭时过期。
- domain=domain:指定 Cookie 的有效域,控制哪些域可以访问该 Cookie。
- path=path:指定 Cookie 的有效路径,控制哪些路径下的页面可以访问该 Cookie。
- secure:如果设置了该选项,Cookie 只能通过 HTTPS 协议传输,不能通过 HTTP 协议发送,增加安全性。
- httponly:如果设置了该选项,Cookie 将无法通过 JavaScript 脚本访问,有助于防止跨站脚本攻击(XSS)。
注意事项:每个 Cookie 属性都以分号(;)和空格分隔;名称和值之间使用等号(=)分隔;如果包含特殊字符需进行 URL 编码。
生命周期
- 如果设置了
expires属性,Cookie 将在指定的日期/时间后过期。 - 如果没有设置
expires属性,则 Cookie 默认为会话 Cookie,即当浏览器关闭时过期。
单独使用 Cookie 的问题
如果我们写入的是测试数据还好,但如果写入的是用户的私密数据呢?比如用户名、密码、浏览痕迹等。
本质问题在于这些用户私密数据保存在浏览器(用户端),非常容易被人盗取,更重要的是,一旦泄露就是隐私泄露。这种不安全性促使我们需要引入 Session 机制来配合使用。
HTTP Session
定义
HTTP Session 是服务器用来跟踪用户与服务器交互期间用户状态的机制。由于 HTTP 协议是无状态的(每个请求都是独立的),服务器需要通过 Session 来记住用户的信息。
- 由服务器为每个用户会话创建的临时对象。
- 存储了与特定用户会话相关的信息,包括用户身份验证和会话状态。
工作原理
- 创建 ID:当用户首次访问网站时,服务器会为用户创建一个唯一的 Session ID,并通过 Cookie 将其发送到客户端。
- 传递 ID:客户端在之后的请求中会携带这个 Session ID。
- 识别用户:服务器通过 Session ID 来识别用户,从而获取存储在服务器端的会话信息。
- 存储位置:服务器通常会将 Session 信息存储在内存、数据库或缓存中。
安全性
与 Cookie 相似,由于 Session ID 是在客户端和服务器之间传递的,因此也存在被窃取的风险。但是一般来说,即使 Cookie 被盗取了,用户只泄漏了一个 Session ID,私密信息暂时没有被直接泄露的风险。
可以通过 HTTPS 和设置合适的 Cookie 属性(如 HttpOnly 和 Secure)来增强安全性。
超时和失效
Session 可以设置超时时间,当超过这个时间后,Session 会自动失效。服务器也可以主动使 Session 失效,例如当用户登出时。
Session 相对安全,因为它是服务器创建并管理的。当服务器辨别到 Session ID 有被盗取的风险,只要让 Session ID 失效就可以了。那么服务器是怎么知道这个 Client 对应的 Session 是非法的呢?这通常需要结合业务逻辑。
比如 QQ 在异地登录的时候,腾讯的服务端会识别到异常,需要我们重新扫码验证才能异地登录,这里的异地登录就是潜在被盗用的风险场景。
总结
HTTP Cookie 和 Session 都是用于在 Web 应用中跟踪用户状态的机制。Cookie 是存储在客户端的,而 Session 是存储在服务器端的。它们各有优缺点,通常在实际应用中会结合使用,以达到最佳的用户体验和安全性。
需要明确的是,Session 和 Cookie 都不是绝对安全的!Session 只是比 Cookie 相对安全一些。所以我们要认识到,在网络世界里,几乎没有东西是绝对安全的,安全是一个持续对抗的过程。

