跳到主要内容

4. 服务器要求 (Server Requirements)

本节描述 Cookie 和 Set-Cookie 头的行为良好配置文件的语法和语义.

4.1. Set-Cookie

Set-Cookie HTTP 响应头用于从服务器向用户代理发送 cookie.

4.1.1. 语法 (Syntax)

非正式地说, Set-Cookie 响应头包含头名称 "Set-Cookie", 后跟 ":" 和一个 cookie. 每个 cookie 以 name-value-pair 开始, 后跟零个或多个属性-值对. 服务器 SHOULD NOT 发送不符合以下语法的 Set-Cookie 头:

set-cookie-header = "Set-Cookie:" SP set-cookie-string set-cookie-string = cookie-pair *( ";" SP cookie-av ) cookie-pair = cookie-name "=" cookie-value cookie-name = token cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E ; US-ASCII characters excluding CTLs, ; whitespace DQUOTE, comma, semicolon, ; and backslash token = <token, defined in [RFC2616], Section 2.2>

cookie-av = expires-av / max-age-av / domain-av / path-av / secure-av / httponly-av / extension-av expires-av = "Expires=" sane-cookie-date sane-cookie-date = <rfc1123-date, defined in [RFC2616], Section 3.3.1> max-age-av = "Max-Age=" non-zero-digit *DIGIT ; In practice, both expires-av and max-age-av ; are limited to dates representable by the ; user agent. non-zero-digit = %x31-39 ; digits 1 through 9 domain-av = "Domain=" domain-value domain-value = <subdomain> ; defined in [RFC1034], Section 3.5, as ; enhanced by [RFC1123], Section 2.1 path-av = "Path=" path-value path-value = <any CHAR except CTLs or ";"> secure-av = "Secure" httponly-av = "HttpOnly" extension-av = <any CHAR except CTLs or ";">

注意, 上述某些语法术语引用了使用不同语法记法的文档, 而本文档使用来自 [RFC5234] 的 ABNF.

cookie-value 的语义不由本文档定义.

为了最大化与用户代理的兼容性, 希望在 cookie-value 中存储任意数据的服务器 SHOULD 对该数据进行编码, 例如使用 Base64 [RFC4648].

set-cookie-string 中由 cookie-av 术语产生的部分称为属性. 为了最大化与用户代理的 兼容性, 服务器 SHOULD NOT 在同一个 set-cookie-string 中生成两个同名属性. (用户代理如何处理这种情况见第 5.3 节.)

服务器 SHOULD NOT 在同一响应中包含多个具有相同 cookie-name 的 Set-Cookie 头字段. (用户代理如何处理这种情况见第 5.2 节.)

如果服务器并发地向用户代理发送多个包含 Set-Cookie 头的响应 (例如通过多个套接字 与用户代理通信时), 这些响应会产生 "race condition", 可能导致不可预测的行为.

NOTE: 某些现有用户代理对两位数年份的解释不同. 为避免兼容性问题, 服务器 SHOULD 使用要求四位数年份的 rfc1123-date 格式.

NOTE: 某些用户代理将 cookie 中的日期作为 32 位 UNIX time_t 值存储和处理. 某些系统中支持 time_t 处理的库存在实现缺陷, 可能导致这类用户代理错误处理 2038 年之后的日期.

4.1.2. 语义 (非规范性) (Semantics, Non-Normative)

本节描述 Set-Cookie 头的简化语义. 这些语义已经足够详细, 可用于理解服务器对 cookie 的最常见用法. 完整语义在第 5 节中描述.

当用户代理收到 Set-Cookie 头时, 用户代理会将 cookie 与其属性一起存储. 随后, 当用户代理发起 HTTP 请求时, 用户代理会在 Cookie 头中包含适用且未过期的 cookie.

如果用户代理收到一个新 cookie, 其 cookie-name, domain-value 和 path-value 与 已存储 cookie 相同, 则现有 cookie 会被逐出并由新 cookie 替换. 注意, 服务器可以 通过向用户代理发送一个 Expires 属性值为过去时间的新 cookie 来删除 cookie.

除非 cookie 的属性另有指示, 否则该 cookie 只会返回给源服务器 (例如不会返回给任何 子域), 并在当前会话 (由用户代理定义) 结束时过期. 用户代理会忽略无法识别的 cookie 属性 (但不会忽略整个 cookie).

4.1.2.1. Expires 属性 (The Expires Attribute)

Expires 属性指示 cookie 的最大生存期, 表示为 cookie 过期的日期和时间. 用户代理不要求一直保留 cookie 直到指定日期已过. 事实上, 用户代理经常因内存压力 或隐私顾虑而逐出 cookie.

4.1.2.2. Max-Age 属性 (The Max-Age Attribute)

Max-Age 属性指示 cookie 的最大生存期, 表示为距离 cookie 过期的秒数. 用户代理 不要求在指定时长内保留该 cookie. 事实上, 用户代理经常因内存压力或隐私顾虑而逐出 cookie.

  NOTE: 某些现有用户代理不支持 Max-Age 属性. 不支持 Max-Age 属性的用户代理会
忽略该属性.

如果 cookie 同时具有 Max-Age 和 Expires 属性, Max-Age 属性优先, 并控制该 cookie 的过期日期. 如果 cookie 既没有 Max-Age 属性也没有 Expires 属性, 用户代理会保留该 cookie 直到 "the current session is over" (由用户代理定义).

4.1.2.3. Domain 属性 (The Domain Attribute)

Domain 属性指定 cookie 将被发送到哪些主机. 例如, 如果 Domain 属性的值为 "example.com", 用户代理在向 example.com, www.example.comwww.corp.example.com 发起 HTTP 请求时会在 Cookie 头中包含该 cookie. (注意, 前导 %x2E (".") 即使存在也会被忽略, 尽管该字符并不被允许, 但尾随 %x2E (".") 如果存在, 会导致用户代理忽略该属性.) 如果服务器省略 Domain 属性, 用户代理只会 将该 cookie 返回给源服务器.

  WARNING: 某些现有用户代理会将缺失的 Domain 属性当作 Domain 属性存在且包含
当前主机名来处理. 例如, 如果 example.com 返回一个没有 Domain 属性的 Set-Cookie
头, 这些用户代理也会错误地将该 cookie 发送给 www.example.com.

除非 Domain 属性为 cookie 指定的作用域包含源服务器, 否则用户代理会拒绝该 cookie. 例如, 用户代理会从 foo.example.com 接受 Domain 属性为 "example.com" 或 "foo.example.com" 的 cookie, 但不会接受 Domain 属性为 "bar.example.com" 或 "baz.foo.example.com" 的 cookie.

NOTE: 出于安全原因, 许多用户代理被配置为拒绝对应于 "public suffixes" 的 Domain 属性. 例如, 某些用户代理会拒绝 "com" 或 "co.uk" 这样的 Domain 属性. (更多信息见 第 5.3 节.)

4.1.2.4. Path 属性 (The Path Attribute)

每个 cookie 的作用域被限制为一组路径, 由 Path 属性控制. 如果服务器省略 Path 属性, 用户代理会使用 request-uri 路径组件的 "directory" 作为默认值. (更多细节见第 5.1.4 节.)

只有当 request-uri 的路径部分匹配 cookie 的 Path 属性 (或是其子目录) 时, 用户代理 才会在 HTTP 请求中包含该 cookie, 其中 %x2F ("/") 字符被解释为目录分隔符.

尽管 Path 属性看起来可用于隔离给定主机内不同路径之间的 cookie, 但不能依赖它来提供 安全性 (见第 8 节).

4.1.2.5. Secure 属性 (The Secure Attribute)

Secure 属性将 cookie 的作用域限制为 "secure" 信道 (其中 "secure" 由用户代理定义). 当 cookie 具有 Secure 属性时, 只有请求通过安全信道传输时, 用户代理才会在 HTTP 请求 中包含该 cookie (通常是基于传输层安全 (Transport Layer Security, TLS) [RFC2818] 的 HTTP).

尽管 Secure 属性看起来可用于保护 cookie 免受主动网络攻击者影响, 但它只保护 cookie 的机密性. 主动网络攻击者可以从不安全信道覆盖 Secure cookie, 从而破坏其完整性 (更多 细节见第 8.6 节).

4.1.2.6. HttpOnly 属性 (The HttpOnly Attribute)

HttpOnly 属性将 cookie 的作用域限制为 HTTP 请求. 特别地, 该属性指示用户代理在通过 "non-HTTP" API (例如向脚本暴露 cookie 的 Web 浏览器 API) 提供 cookie 访问时省略该 cookie.

注意, HttpOnly 属性独立于 Secure 属性: 一个 cookie 可以同时具有 HttpOnly 和 Secure 属性.

4.2. Cookie

4.2.1. 语法 (Syntax)

用户代理在 Cookie 头中将已存储的 cookie 发送给源服务器. 如果服务器符合第 4.1 节的 要求 (并且用户代理符合第 5 节的要求), 用户代理将发送符合以下语法的 Cookie 头:

cookie-header = "Cookie:" OWS cookie-string OWS cookie-string = cookie-pair *( ";" SP cookie-pair )

4.2.2. 语义 (Semantics)

每个 cookie-pair 表示用户代理存储的一个 cookie. cookie-pair 包含用户代理在 Set-Cookie 头中收到的 cookie-name 和 cookie-value.

注意, cookie 属性不会被返回. 特别地, 服务器无法仅凭 Cookie 头确定 cookie 何时过期, 该 cookie 对哪些主机有效, 对哪些路径有效, 或者它是否使用 Secure 或 HttpOnly 属性设置.

Cookie 头中各个 cookie 的语义不由本文档定义. 服务器预期为这些 cookie 赋予应用特定语义.

尽管 cookie 在 Cookie 头中按线性方式序列化, 服务器 SHOULD NOT 依赖序列化顺序. 特别地, 如果 Cookie 头包含两个同名 cookie (例如使用不同 Path 或 Domain 属性设置的 cookie), 服务器 SHOULD NOT 依赖这些 cookie 在头中出现的顺序.