Cookie 的 Domain 和 Path 属性有什么作用?

彻底搞懂 Cookie 的作用域:Domain 与 Path 属性详解及安全实践
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.com或Domain=.example.com(注意开头的点)。 - 不能跨一级域名设置:在
a.example.com下,不能将 Domain 设为.baidu.com。
匹配规则
浏览器发送请求时,会检查 Cookie 的 Domain 属性是否与请求的域名匹配:
- 精确匹配:
Domain=a.example.com只匹配a.example.com。 - 子域匹配:
Domain=.example.com匹配a.example.com、b.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.com,Path=/ |
跨子域共享,同时全路径可用 |
| 敏感的接口认证 Cookie | Domain=api.example.com,Path=/ + 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 属性可以简单实现:
- 认证中心(如
auth.example.com)在用户登录成功后,设置一个Domain=.example.com的 Cookie。 - 业务子域(如
app1.example.com、app2.example.com)在收到请求时,自动携带该 Cookie。 - 各业务子域通过解密或校验 Cookie 中的 Token,识别用户身份。
这种方案的局限在于:所有子域必须共享同一根域名。若跨一级域名(如 example.com 与 example.cn),则需使用更复杂的 OAuth 或 CAS 方案。
6.3 前端开发中的调试技巧
- 在 Chrome 开发者工具中查看 Cookie:
Application→Cookies,可以看到每个 Cookie 的 Domain、Path 等属性。 - 如果发现 Cookie 未被携带,首先检查请求的域名和路径是否匹配 Domain/Path 设置。
- 注意:
HttpOnly的 Cookie 无法被 JavaScript 读取,但依然会被浏览器自动携带。
7. 总结:一张表记住核心要点
| 属性 | 作用 | 匹配规则 | 常见误区 |
|---|---|---|---|
| Domain | 控制域名范围,支持子域共享 | 当前域或其父域;点开头可匹配子域 | 误设顶级域(如 .com)造成安全风险;忘记加前缀点导致子域不共享 |
| Path | 控制路径范围,实现模块隔离 | 请求路径以 Path 值为前缀 | 混淆目录匹配与字符串前缀匹配;误以为 /api 匹配 /api2 |
最终建议:
- 遵循 最小作用域原则:只在必要范围内设置 Domain 和 Path。
- 敏感 Cookie 必须搭配
HttpOnly和Secure属性,并严格控制 Domain。 - 跨子域共享时,Domain 应设置为带点的父域(如
.example.com)。 - 定期审计项目中 Cookie 的 Domain/Path 设置,避免作用域过宽带来的安全风险。
理解并正确使用 Cookie 的 Domain 与 Path,是构建安全、可维护的 Web 应用的基础。希望本文能帮你彻底掌握这两个关键属性,写出更健壮的代码。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)