使用 HTTP Cookie

365娱乐场奖金 2026-01-25 14:00:17 作者: admin 阅读: 3430
使用 HTTP Cookie

使用 HTTP Cookie一个**cookie**(也称为网络 cookie 或浏览器 cookie)是服务器发送到用户网络浏览器的一小段数据。浏览器可以存储 cookie、创建新 cookie、修改现有 cookie 并将其与后续请求一起发送回同一服务器。Cookie 使 Web 应用程序能够存储有限数量的数据并记住状态信息;默认情况下,HTTP 协议是无状态的。

在本文中,我们将探讨 cookie 的主要用途,解释使用 cookie 的最佳实践,并了解其隐私和安全影响。

Cookie 的用途通常,服务器将使用 HTTP cookie 的内容来确定不同的请求是否来自同一浏览器/用户,然后发出个性化或通用响应。以下是用户登录系统的一个非常简单的描述

用户将登录凭据发送到服务器,例如通过表单提交。

如果凭据正确,服务器会更新 UI 以指示用户已登录,并使用包含会话 ID 的 cookie 响应,该会话 ID 记录其在浏览器上的登录状态。

稍后,用户移动到同一站点上的另一个页面。浏览器将包含会话 ID 的 cookie 与相应的请求一起发送,以指示它仍然认为用户已登录。

服务器检查会话 ID,如果它仍然有效,则向用户发送新页面的个性化版本。如果无效,则删除会话 ID,并向用户显示页面的通用版本(或者可能显示“访问被拒绝”消息并要求用户重新登录)。

Cookie 主要用于三个目的

会话管理:用户登录状态、购物车内容、游戏得分或服务器需要记住的任何其他与用户会话相关的信息。

个性化:用户偏好,例如显示语言和 UI 主题。

跟踪:记录和分析用户行为。

数据存储在 Web 早期,由于没有其他选择,Cookie 用于一般的客户端数据存储目的。现在建议使用现代存储 API,例如Web 存储 API(localStorage 和 sessionStorage)和IndexedDB。

它们专为存储而设计,从不向服务器发送数据,并且没有使用 cookie 进行存储的其他缺点。

浏览器通常限制每个域的最大 cookie 数量(因浏览器而异,通常为数百个),以及每个 cookie 的最大大小(通常为 4KB)。存储 API 可以存储更多数据。

Cookie 会随每个请求一起发送,因此它们会降低性能(例如在缓慢的移动数据连接上),尤其是在您设置了许多 cookie 的情况下。

注意:要查看存储的 cookie(以及网页正在使用的其他存储),您可以在 Firefox 开发者工具中使用存储检查器,或在 Chrome 开发者工具中使用应用程序面板。

创建、删除和更新 Cookie在收到 HTTP 请求后,服务器可以发送一个或多个带有响应的Set-Cookie标头,每个标头将设置一个单独的 cookie。简单的 cookie 通过指定名称-值对来设置,如下所示

httpSet-Cookie: =

以下 HTTP 响应指示接收浏览器存储一对 cookie

httpHTTP/2.0 200 OK

Content-Type: text/html

Set-Cookie: yummy_cookie=choco

Set-Cookie: tasty_cookie=strawberry

[page content]

注意:了解如何在各种服务器端语言/框架中使用Set-Cookie标头:PHP、Node.JS、Python、Ruby on Rails。

当发出新请求时,浏览器通常会将先前存储的当前域的 cookie 发送回服务器,位于CookieHTTP 标头中

httpGET /sample_page.html HTTP/2.0

Host: www.example.org

Cookie: yummy_cookie=choco; tasty_cookie=strawberry

删除:定义 cookie 的生命周期您可以指定一个过期日期或时间段,在此之后应删除 cookie 并且不再发送。根据在创建 cookie 时Set-Cookie标头中设置的属性,它们可以是永久或会话 cookie

永久 cookie 在Expires属性中指定的日期后删除httpSet-Cookie: id=a3fWa; Expires=Thu, 31 Oct 2021 07:28:00 GMT;

或在Max-Age属性中指定的时间段后httpSet-Cookie: id=a3fWa; Max-Age=2592000

注意:Expires比Max-Age可用时间更长,但是Max-Age出错的可能性更小,并且在两者都设置时优先。这样做的原因是,当您设置Expires日期和时间时,它们相对于设置 cookie 的客户端。如果服务器设置为不同的时间,这可能会导致错误。

会话cookie——没有Max-Age或Expires属性的 cookie——在当前会话结束时删除。浏览器定义“当前会话”何时结束,一些浏览器在重新启动时使用会话恢复。这可能导致会话 cookie 持续无限期。

注意:如果您的网站对用户进行身份验证,则应重新生成并重新发送会话 cookie,即使是已存在的 cookie,只要用户进行身份验证。此方法有助于防止会话固定攻击,在这些攻击中,第三方可以重用用户的会话。

有一些技术旨在在 cookie 被删除后重新创建它们。这些被称为“僵尸”cookie。这些技术违反了用户隐私和控制的原则,可能违反数据隐私法规,并且可能会使使用它们的网站承担法律责任。

更新 cookie 值要通过 HTTP 更新 cookie,服务器可以发送一个带有现有 cookie 的名称和新值的Set-Cookie标头。例如

httpSet-Cookie: id=new-value

您可能出于多种原因想要这样做,例如,如果用户更新了其偏好设置并且应用程序希望反映客户端数据中的更改(您也可以使用客户端存储机制(例如Web 存储)来做到这一点)。

通过 JavaScript 更新 cookie

在浏览器中,您可以使用Document.cookie属性或异步Cookie Store API通过 JavaScript 创建新的 cookie。请注意,以下所有示例都使用Document.cookie,因为它是支持最广泛/最成熟的选项。

jsdocument.cookie = "yummy_cookie=choco";

document.cookie = "tasty_cookie=strawberry";

您还可以访问现有 cookie 并为其设置新值,前提是HttpOnly属性未在其上设置(即在创建它的Set-Cookie标头中)

jsconsole.log(document.cookie);

// logs "yummy_cookie=choco; tasty_cookie=strawberry"

document.cookie = "yummy_cookie=blueberry";

console.log(document.cookie);

// logs "tasty_cookie=strawberry; yummy_cookie=blueberry"

请注意,出于安全目的,您不能通过在启动请求时直接发送更新的Cookie标头来更改 cookie 值,即通过fetch()或XMLHttpRequest。请注意,您不应允许 JavaScript 修改 cookie 也有充分的理由——即在创建期间设置HttpOnly。有关更多详细信息,请参阅安全部分。

安全当您将信息存储在 cookie 中时,默认情况下,所有 cookie 值对最终用户都是可见的,并且可以由最终用户更改。您真的不希望您的 cookie 被滥用——例如被恶意攻击者访问/修改,或发送到不应发送到的域。潜在后果的范围从令人烦恼——应用程序无法正常工作或表现出奇怪的行为——到灾难性的。例如,犯罪分子可以窃取会话 ID 并使用它来设置一个 cookie,使其看起来像他们以其他人的身份登录,从而在此过程中控制其银行或电子商务帐户。

您可以通过多种方式保护您的 cookie,本节将对此进行审查。

阻止访问您的 cookie您可以通过两种方式之一确保 cookie 以安全的方式发送并且不会被意外的方或脚本访问:使用Secure属性和HttpOnly属性

httpSet-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly

具有Secure属性的 cookie 仅通过 HTTPS 协议上的加密请求发送到服务器。它永远不会与不安全的 HTTP 一起发送(本地主机除外),这意味着中间人攻击者无法轻松访问它。不安全的站点(URL 中带有http:)无法设置具有Secure属性的 cookie。但是,不要假设Secure可以防止所有对 cookie 中敏感信息的访问。例如,拥有客户端硬盘访问权限(或 JavaScript 如果未设置HttpOnly属性)的人可以读取和修改信息。

具有HttpOnly属性的 cookie 不能被 JavaScript 修改,例如使用Document.cookie;它只能在到达服务器时修改。例如,保留用户会话的 cookie 应设置HttpOnly属性——让它们对 JavaScript 可用将非常不安全。此预防措施有助于减轻跨站点脚本(XSS)攻击。

注意:根据应用程序,您可能希望使用服务器查找的不透明标识符,而不是将敏感信息直接存储在 cookie 中,或者调查替代的身份验证/机密性机制,例如JSON Web 令牌。

定义 cookie 发送到的位置Domain和Path属性定义 cookie 的范围:cookie 发送到的 URL。

Domain 属性指定哪个服务器可以接收 Cookie。如果指定了,Cookie 可以在指定的服务器及其子域上访问。例如,如果您从 mozilla.org 设置了 Domain=mozilla.org,则 Cookie 可在该域及其子域(如 developer.mozilla.org)上使用。httpSet-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly; Domain=mozilla.org

如果 Set-Cookie 头部没有指定 Domain 属性,则 Cookie 可在设置它的服务器上使用,但不能在其子域上使用。因此,指定 Domain 比省略它限制性更小。请注意,服务器只能将其 Domain 属性设置为其自身域或父域,不能设置为子域或其他域。因此,例如,域为 foo.example.com 的服务器可以将属性设置为 example.com 或 foo.example.com,但不能设置为 bar.foo.example.com 或 elsewhere.com(尽管 Cookie 仍会发送到诸如 bar.foo.example.com 的子域)。有关更多详细信息,请参阅无效域。

Path 属性指示一个 URL 路径,该路径必须存在于请求的 URL 中才能发送 Cookie 头部。例如httpSet-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly; Path=/docs

%x2F("/")字符被视为目录分隔符,子目录也匹配。例如,如果您设置 Path=/docs,则以下请求路径匹配

/docs

/docs/

/docs/Web/

/docs/Web/HTTP

但以下请求路径不匹配

/

/docsets

/en-US/docs

使用SameSite控制第三方 CookieSameSite 属性允许服务器指定是否/何时将 Cookie 与跨站点请求一起发送 - 即 第三方 Cookie。跨站点请求是指站点(可注册的域)和/或方案(http 或 https)与用户当前访问的站点不匹配的请求。这包括单击其他站点上的链接以导航到您的站点的请求,以及嵌入的第三方内容发送的任何请求。

SameSite 有助于防止信息泄漏,维护用户隐私,并提供一些针对跨站点请求伪造攻击的保护。它采用三个可能的值:Strict、Lax 和 None

Strict 使浏览器仅在响应来自 Cookie 原站点的请求时发送 Cookie。当您拥有与始终位于初始导航之后的函数相关的 Cookie 时,例如身份验证或存储购物车信息,应使用此选项。httpSet-Cookie: cart=110045_77895_53420; SameSite=Strict

注意:用于敏感信息的 Cookie 也应具有较短的生命周期。

Lax 类似,但当用户导航到 Cookie 原站点时,浏览器也会发送 Cookie(即使用户来自不同的站点)。这对于影响站点显示的 Cookie 很有用 - 例如,您的网站上可能包含合作伙伴产品信息以及联盟链接。当用户点击该链接访问合作伙伴网站时,他们可能希望设置一个 Cookie 来表明已点击了联盟链接,从而显示奖励横幅并在购买产品时提供折扣。httpSet-Cookie: affiliate=e4rt45dw; SameSite=Lax

None 指定在源请求和跨站点请求中都发送 Cookie。如果您希望将 Cookie 与从嵌入在其他站点中的第三方内容(例如广告技术或分析提供商)发出的请求一起发送,这将很有用。请注意,如果设置了 SameSite=None,则还必须设置 Secure 属性 - SameSite=None 需要安全上下文。httpSet-Cookie: widget_session=7yjgj57e4n3d; SameSite=None; Secure; HttpOnly

如果没有设置 SameSite 属性,则 Cookie 默认情况下将被视为 Lax。

Cookie 前缀由于 Cookie 机制的特性,服务器无法确认 Cookie 是否是从安全来源设置的,甚至无法确定 Cookie 最初是在哪里设置的。

子域上的易受攻击的应用程序可以使用 Domain 属性设置 Cookie,这使得可以访问所有其他子域上的该 Cookie。这种机制可能被滥用于会话固定攻击。有关主要缓解方法,请参阅会话固定。

但是,作为纵深防御措施,您可以使用 Cookie 前缀来断言有关 Cookie 的特定事实。有两个前缀可用

__Host-:如果 Cookie 名称具有此前缀,则仅当它也用 Secure 属性标记、从安全来源发送、不包含 Domain 属性且 Path 属性设置为 / 时,才会在 Set-Cookie 标头中接受它。换句话说,Cookie 是域锁定的。

__Secure-:如果 Cookie 名称具有此前缀,则仅当它用 Secure 属性标记并从安全来源发送时,才会在 Set-Cookie 标头中接受它。这比 __Host- 前缀弱。

浏览器将拒绝不符合其限制的具有这些前缀的 Cookie。这确保了具有前缀的子域创建的 Cookie 仅限于子域或完全被忽略。由于应用程序服务器仅在确定用户是否已通过身份验证或 CSRF 令牌是否正确时检查特定的 Cookie 名称,因此这有效地充当了针对会话固定的防御措施。

注意:在服务器端,Web 应用程序必须检查包含前缀的完整 Cookie 名称。用户代理不会在请求的 Cookie 标头中发送 Cookie 之前从 Cookie 中删除前缀。

有关 Cookie 前缀和浏览器支持的当前状态的更多信息,请参阅Set-Cookie 参考文章的前缀部分。

隐私和跟踪前面我们讨论了如何使用 SameSite 属性来控制何时发送第三方 Cookie,以及这如何帮助维护用户隐私。隐私在构建网站时是一个非常重要的考虑因素,如果做得好,可以建立用户信任。如果做得不好,它可能会完全破坏这种信任并导致各种其他问题。

第三方 Cookie 可以通过