Cookie在根域名和子域名之间默认是不共享的,但通过设置Domain属性为根域名,即可实现跨子域名的统一共享;隔离则依赖未设置Domain属性时的主机名精确匹配机制以及浏览器对第三方Cookie的拦截策略。
Cookie的归属权:根域名与子域名的默认隔离规则
Cookie在浏览器端的存储和发送,遵循一套严格的“域名归属”规则,这套规则的底层逻辑,可以理解为浏览器给每个Cookie都贴上了一张写着“我是谁家的”的任务标签,当浏览器向服务器发起请求时,只会带上标签与当前访问域名完全匹配的Cookie。
为什么默认情况下子域名读取不到根域名的Cookie?
假设你登录了 example.com,服务器返回了一个名为 session_id 的Cookie,如果没有显式指定Cookie的 Domain 属性,浏览器就会把这个Cookie的归属权划给 example.com 这个具体的主机名,当你访问 www.example.com 或 m.example.com 时,浏览器会认为这是两个完全不同的站点,出于安全的默认策略,它不会把带有 example.com 标签的Cookie发送出去。
业内专家指出,这种默认行为保护了子域名环境下的应用安全,防止某个子域被攻破后,攻击者轻松窃取其他子域的用户会话。
子域名Cookie隔离的实际应用场景
这种隔离机制在实际开发中经常被用于区分环境,比如你在 api.example.com 下设置了一个Cookie,它只负责描述API网关的调用偏好,由于默认隔离,这个Cookie绝不会跑到 shop.example.com 的页面上干扰购物车的渲染,对于很多开发者来说,这种隔离让子域名可以视为独立的Cookie隔离区,便于进行灰度测试或独立部署。
跨子域名共享的钥匙:Domain属性怎么设?
要实现你期望的“一个账号密码,全家通用”的效果,比如登录了 www.example.com,跳转到 mail.example.com 时保持登录态,就必须手动干预Cookie的生成规则,这里的关键就在于 Domain 属性的设置。
设置Domain为根域名的标准操作路径
在服务端生成Cookie的响应头中,你需要指定 Domain=example.com,这意味着你授权浏览器,该Cookie不仅属于 example.com,也属于它的所有子域名,从根本上将Cookie的作用域从主机名提升到了注册域(即根域名)层级。
以常见的后端语言为例,代码逻辑如下:
- Java (Servlet):
response.setHeader("Set-Cookie", "token=value; Domain=.example.com; Path=/");注意,这里的.example.com和example.com在大多数现代浏览器中是等效的。 - Node.js (Express):
res.cookie('token', 'value', { domain: '.example.com', path: '/' }); - Nginx 反向代理配置:在
proxy_cookie_domain指令中,将后端返回的domain=localhost替换为domain=.example.com。
实操时有一个硬性前置条件:只有当前响应的主机名是该Domain的后缀,才能设置成功,也就是说,你只能在 www.example.com 的响应里把Domain设为 example.com,但不能设为 other.com,这是浏览器的强制安全限制,任何服务端代码都无法绕过。
Path路径参数在共享中的协同作用
除了Domain,另一个关键属性是 Path,它控制的是同一域名下的URL路径范围,对于跨子域名共享来说,必须将 Path=/ 设置为根路径,才能保证整个站点下的所有页面都能接收到这个Cookie。Path 被限定在 /admin,那么即使 Domain 设置了根域名,在 /user 路径下也是无效的。
第三方Cookie隔离:根域名共享的现代拦路虎
即便你已经正确设置了 Domain=.example.com,在现代浏览器隐私策略下,跨站共享仍可能面临隔离,这就必须区分第一方Cookie和第三方Cookie的概念。
什么是同站与跨站的真实差异?
同站(Same-Site)判定标准遵循 站点(Scheme + Registrable Domain) 规则。www.example.com 和 mail.example.com 属于同站,因为它们的注册域(example.com)和协议(https)一致,在这种同站上下文中,Cookie可以正常携带,不存在拦截问题。
但当子域名跳转到完全独立的根域名,例如从 example.com 跳转至 adpartner.com 时,adpartner.com 的Cookie在 example.com 页面上就被视为第三方Cookie,浏览器会优先参考 SameSite 属性。
SameSite属性如何影响根域名共享
随着对用户隐私保护要求的提升,主流浏览器(Chrome、Safari、Firefox)对Cookie的策略已倾向更严格的隔离,当你的子域名需要在第三方上下文中发送Cookie时,必须显式声明 SameSite=None; Secure,否则,浏览器会拒绝在跨站请求中携带该Cookie,导致支付回调、单点登录跳转等场景失效。
这一层隔离逻辑是现行互联网下最需要注意的:SameSite=Lax 是默认值,它限制了跨站POST请求的Cookie发送;SameSite=Strict 则直接断子绝孙;SameSite=None 必须配合 Secure(要求HTTPS)才能生效。
本地存储与Cookie:筛选共享方案时的取舍
在互联网大厂的多业务线产品中,根域名与子域名的登录态共享往往不单靠Cookie,很多人问,既然Cookie这么麻烦,能不能绕过去?现在行业共识里有一个替代方案,就是用 LocalStorage 和 postMessage。
- 主域名
example.com登录后,将token写入根域名下的LocalStorage。 - 子域名
app.example.com通过window.postMessage向example.com发起请求获取token。
这种方案避开了Cookie作用域的条条框框,但在换取安全性的代价上却付出更多,LocalStorage 没有内置的过期保护机制,一旦发生XSS攻击,数据泄露风险远高于带 HttpOnly 标记的Cookie,在主流安全测试标准中,修复XSS漏洞的优先级远高于配置错误,因此绝大对数场景下,设置Domain属性仍是成本最低、兼容性最好的做法。
实战排查Cookie不共享问题的三条路径
假设你已经按文档配置了代码,子域名下还是拿不到Cookie,此时解决问题的排查路径比看网络教程更关键。
第一步:检查浏览器开发者工具
在Chrome浏览器中按下F12,进入Application面板,点开Cookies树形菜单。
- 如果能看到根域名Cookie,但发送出去的是无效值,检查该Cookie的Domain列是否为空。
- 如果出现在子域名的Cookie列表中,但请求头没有携带,排查是否是
SameSite属性被拦。 - 这里可以看到Domain显示为
.example.com,才属于正确配置的表象特征。
第二步:验证请求方法上下文
不同浏览器对Cookie的隔离还体现在跨域请求中,如果前端使用了Ajax从
mail.example.com 向 www.example.com 发送请求,且开启了 credentials: 'include',后端需要配置 Access-Control-Allow-Credentials: true,后端不能把 Access-Control-Allow-Origin 设置为通配符 ,必须指定具体的来源域名,这种CORS与Cookie的双重条件限制,经常让开发者误以为到了子域名就是同源可访问,属实踩了坑。
第三步:区分Set-Cookie的过期时间
会话型Cookie(Session Cookie)在不设置 Expires 或 Max-Age 时,只存在于内存中,关闭浏览器即丢失,如果通过脚本动态写入子域名的Cookie,仅设置了 Domain 而忽略了持久化周期,刷新页面后会发现Cookie引脚消失,看起来像是被隔离了,实际上是生命周期终止。
共享与隔离的边界掌握在开发配置手中
Cookie在根域名和子域名间的流动,本质上不是自由漫游,而是受浏览器隐私模型约束的受控通行,共享的关键在于主动声明 Domain 和 Path,隔离的底线则依赖主机名匹配与 SameSite 策略,掌握了这两点,你就能在不同业务线之间找到数据协作和数据保护的平衡点。
Q&A:Cookie跨域共享常见疑问解析
Cookie根域名和子域名间的共享会覆盖子域名原有的同名Cookie吗?
会共存,但浏览器发送时会同时携带两个同名Cookie,服务端通常只能读取到其中一个,具体规则取决于Cookie的Path和Domain的优先级排序,Path匹配优先级最高,其次是创建时间更早的Cookie,实际开发中建议规避同名冲突。
如何让子域名上删除根域名的Cookie?
要删除根域名级别的Cookie,必须发送一个相同Domain和Path的Set-Cookie,并将 Expires 设置为过去的时间(如1970年1月1日),仅删除子域名路径下的Cookie并不会影响根域名的会话状态,因此需要前端统一定位到根域操作。
在没有设置Domain属性的情况下,子域名能通过JS读取根域名的Cookie吗?
不能,根域名的Cookie未指定Domain时,其作用域精确指向根域名路径,子域名的JavaScript环境无法访问 document.cookie 读取父域数据,这是浏览器在Domian属性上的强制沙箱行为,数据流通必须依赖显式的Domain声明。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/628061.html





