在这里插入图片描述

1. 引言:小区门禁与单元楼钥匙的启示

想象你住在一个大型小区。进小区大门需要刷门禁卡,进自家单元楼还需要单元钥匙。这两把钥匙各司其职:门禁卡决定你能进哪个小区(Domain),单元钥匙决定你能进哪栋楼(Path)。小区物业(浏览器)会严格执行规则——拿着A小区的门禁卡,进不了B小区;拿着3号楼的单元钥匙,开不了5号楼的门。

在 Web 世界中,Cookie 的 Domain 和 Path 属性扮演的正是这样的角色。它们共同定义了 Cookie 的“活动范围”:Domain 控制哪些域名可以接收这个 Cookie,Path 控制同一域名下哪些路径可以接收。如果设置不当,要么本该共享的 Cookie 无法传递,要么不该暴露的 Cookie 被错误携带,引发安全风险。

本文将从基础概念讲起,深入剖析 Domain 和 Path 的作用机制、匹配规则、常见误区,并给出生产环境的最佳实践。


2. 前置知识:Cookie 的基本携带机制

在深入 Domain 和 Path 之前,我们先简单回顾一下 Cookie 的传递规则,这有助于理解后文的作用域概念。

  • Cookie 由服务器生成:通过 HTTP 响应头 Set-Cookie 发给浏览器。
  • 浏览器自动携带:后续请求中,浏览器会根据域名路径,决定是否在 Cookie 请求头中携带某个 Cookie。
  • 同源策略对 Cookie 的影响较弱:Cookie 的携带主要取决于 Domain 和 Path 的匹配,而非严格的同源(协议、端口不一致也可能携带,但安全属性会限制)。

默认情况下,Cookie 的作用域是当前请求的域名和路径。例如,你在 https://a.example.com/app1/page.html 设置的 Cookie,默认只会被 a.example.com 域名下的页面携带,且路径前缀必须匹配 /app1/


3. Domain 属性:控制 Cookie 的“小区范围”

3.1 是什么?

Domain 属性指定了 Cookie 可被发送到的域名范围。它的默认值是当前请求的完整域名(不含子域)。例如,在 a.example.com 上设置的 Cookie,默认 Domain=a.example.com,仅该域名可以访问。

3.2 为什么需要它?

在实际应用中,我们常常需要多个子域共享同一份用户登录状态或配置信息。例如:

  • 登录页面在 passport.example.com
  • 主站是 www.example.com
  • 用户中心是 user.example.com

我们希望用户在一个子域登录后,其他子域也能自动识别登录状态。这就需要跨子域共享 Cookie,Domain 属性正是为此设计。

3.3 怎么工作?

设置规则
  • 可以将 Domain 设置为当前域或它的父域(必须是同一根域名下)。例如在 a.example.com 下,可以设置 Domain=a.example.comDomain=.example.com(注意开头的点)。
  • 不能跨一级域名设置:在 a.example.com 下,不能将 Domain 设为 .baidu.com
匹配规则

浏览器发送请求时,会检查 Cookie 的 Domain 属性是否与请求的域名匹配:

  • 精确匹配:Domain=a.example.com 只匹配 a.example.com
  • 子域匹配:Domain=.example.com 匹配 a.example.comb.example.com 等所有二级子域,也匹配 example.com 本身。
代码示例
// 服务器响应头:设置一个跨子域共享的 Cookie
Set-Cookie: sessionId=abc123; Domain=.example.com; Path=/; HttpOnly

// 之后,a.example.com 和 b.example.com 的请求都会携带此 Cookie

3.4 常见误区与安全风险

误区/风险 正确做法
误设顶级域:将 Domain 设为 .com.cn,导致 Cookie 被所有该顶级域下的网站访问,造成严重信息泄露。 严格限制父域层级:只设为当前业务相关的父域(如 .example.com),绝不设为 .com
省略开头的点:设置 Domain=example.com 而非 .example.com。不同浏览器对此处理不一致,部分浏览器可能不支持子域共享。 规范加前缀:建议始终使用点开头的格式,如 .example.com
子域无法删除父域 Cookie:如果父域(如 .example.com)设置了 Cookie,子域无法通过同名 Cookie 覆盖或删除它。 在设计时就规划好 Cookie 的层级,避免后期无法清理。

4. Path 属性:控制 Cookie 的“单元楼层”

4.1 是什么?

Path 属性指定了 Cookie 可被发送到的 URL 路径前缀。默认值为当前请求的路径。

4.2 为什么需要它?

同一域名下可能部署多个独立的应用程序或模块:

  • /shop/ 购物模块
  • /blog/ 博客模块
  • /admin/ 管理后台

我们希望它们的 Cookie 相互隔离,避免购物车的 Cookie 被博客模块误读,或管理员后台的 Cookie 被普通用户页面携带。Path 属性正是为此提供细粒度控制。

4.3 怎么工作?

匹配规则(核心)

请求路径以 Path 值为前缀即匹配。这是字符串前缀匹配,而非目录匹配。

Path 设置 请求路径 是否匹配
/ 任何路径 ✅ 总是匹配
/api /api/users ✅ 匹配(/api 是前缀)
/api /api2 ❌ 不匹配(/api2 不以 /api 开头)
/api /apis ❌ 不匹配(/apis 不以 /api 开头,注意字符串比较)
/api/ /api/v1 ✅ 匹配
/app1 /app1/index.html ✅ 匹配
/app1 /app11/index.html ❌ 不匹配
路径的隔离效果
同一域名 example.com 下:
- Cookie A: Path=/shop
- Cookie B: Path=/blog

访问 /shop/cart → 携带 Cookie A,不携带 Cookie B
访问 /blog/article → 携带 Cookie B,不携带 Cookie A

4.4 常见误区

误区 解释
以为 /api 会匹配 /api/v1 ✅ 会匹配,因为 /api/api/v1 的前缀。
以为 /api 会匹配 /api2 ❌ 不会匹配,字符串比较要求严格前缀。
以为 Path 能跨域 ❌ 不能,Path 只在同域下生效。跨域共享靠 Domain。

5. 两者配合:作用域的组合规则

5.1 组合效应

Cookie 的实际作用域 = Domain 范围 ∩ Path 范围。浏览器会同时校验域名和路径,只有两者都匹配,才会携带 Cookie。

5.2 可视化理解

Domain = .example.com
Path = /api

匹配条件:
1. 域名必须为 example.com 或其子域
2. 请求路径必须以 /api 为前缀

示例:
- https://a.example.com/api/users ✅ 匹配
- https://a.example.com/admin ❌ 路径不匹配
- https://other.com/api ❌ 域名不匹配

5.3 最佳实践:最小作用域原则

在设置 Cookie 时,应遵循最小作用域原则——仅在必要时扩大作用域。

场景 推荐设置 理由
仅当前应用使用的 Cookie Path=/app/,不设 Domain(即默认域名) 限制路径范围,避免被其他应用访问
需要子域共享的登录态 Domain=.example.comPath=/ 跨子域共享,同时全路径可用
敏感的接口认证 Cookie Domain=api.example.comPath=/ + HttpOnly + Secure 限定只在该子域使用,并加上安全属性

6. 知识扩展:安全边界与实际应用

6.1 对 CSRF 攻击的防御意义

CSRF(跨站请求伪造)攻击的核心是利用已认证用户的 Cookie 自动携带机制,诱导用户访问恶意网站,触发第三方请求。

如果 Domain 和 Path 设置过宽(例如 Domain=.example.com + Path=/),那么 example.com 下的所有子域和所有路径的 Cookie 都会被携带,攻击面被放大。例如,如果一个子域被攻破或存在 XSS 漏洞,攻击者就可以获取或利用该 Cookie。

防御措施

  • 将敏感 Cookie 的 Domain 限定在最小必要范围。
  • 结合 HttpOnly(防 XSS)、SameSite(防跨站请求)等属性增强安全。

6.2 跨子域单点登录(SSO)的实现

在微服务架构中,多个子域共用一套认证体系是常见需求。利用 Domain 属性可以简单实现:

  1. 认证中心(如 auth.example.com)在用户登录成功后,设置一个 Domain=.example.com 的 Cookie。
  2. 业务子域(如 app1.example.comapp2.example.com)在收到请求时,自动携带该 Cookie。
  3. 各业务子域通过解密或校验 Cookie 中的 Token,识别用户身份。

这种方案的局限在于:所有子域必须共享同一根域名。若跨一级域名(如 example.comexample.cn),则需使用更复杂的 OAuth 或 CAS 方案。

6.3 前端开发中的调试技巧

  • 在 Chrome 开发者工具中查看 Cookie:ApplicationCookies,可以看到每个 Cookie 的 Domain、Path 等属性。
  • 如果发现 Cookie 未被携带,首先检查请求的域名和路径是否匹配 Domain/Path 设置。
  • 注意:HttpOnly 的 Cookie 无法被 JavaScript 读取,但依然会被浏览器自动携带。

7. 总结:一张表记住核心要点

属性 作用 匹配规则 常见误区
Domain 控制域名范围,支持子域共享 当前域或其父域;点开头可匹配子域 误设顶级域(如 .com)造成安全风险;忘记加前缀点导致子域不共享
Path 控制路径范围,实现模块隔离 请求路径以 Path 值为前缀 混淆目录匹配与字符串前缀匹配;误以为 /api 匹配 /api2

最终建议

  • 遵循 最小作用域原则:只在必要范围内设置 Domain 和 Path。
  • 敏感 Cookie 必须搭配 HttpOnlySecure 属性,并严格控制 Domain。
  • 跨子域共享时,Domain 应设置为带点的父域(如 .example.com)。
  • 定期审计项目中 Cookie 的 Domain/Path 设置,避免作用域过宽带来的安全风险。

理解并正确使用 Cookie 的 Domain 与 Path,是构建安全、可维护的 Web 应用的基础。希望本文能帮你彻底掌握这两个关键属性,写出更健壮的代码。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐