真实面经题目 · 原创解析
如何从后端角度控制cookie的域?
从后端角度控制 cookie 的域,核心是在 HTTP 响应头 Set-Cookie 中设置 Domain 属性。后端只能把 cookie 设置到当前请求主机本身,或其合法父域,不能随意设置到无关域名。是否能被后续请求携带,还受 Domain、Path、Secure、SameSite、浏览器公共后缀规则以及跨站请求策略共同影响。
真实面经题目 · 原创解析
从后端角度控制 cookie 的域,核心是在 HTTP 响应头 Set-Cookie 中设置 Domain 属性。后端只能把 cookie 设置到当前请求主机本身,或其合法父域,不能随意设置到无关域名。是否能被后续请求携带,还受 Domain、Path、Secure、SameSite、浏览器公共后缀规则以及跨站请求策略共同影响。
后端控制 cookie 的域,主要是通过响应头 Set-Cookie 的 Domain 属性。比如用户访问 api.example.com,后端返回 Set-Cookie: sid=xxx; Domain=.example.com; Path=/; HttpOnly; Secure,这样 cookie 可以在 example.com 的子域之间共享。若不设置 Domain,cookie 默认是 host-only,只会回传给当前精确主机,例如只给 api.example.com。需要注意,后端不能把 cookie 设置到任意域,只能设置当前域或合法父域,不能设置到 other.com,也不能设置到 com、co.uk 这类公共后缀。实际回答还要补充 Path 只控制路径范围,不控制域;跨域 Ajax 是否带 cookie 还要配合 SameSite、Secure、CORS 的 credentials 配置;HttpOnly 只限制前端 JS 读取,不影响请求携带。
后端控制 cookie 域的直接入口是 HTTP 响应头 Set-Cookie,而不是前端脚本或请求参数。服务端在响应中写入 Set-Cookie: name=value; Domain=example.com; Path=/,浏览器接收后会根据当前请求的主机名校验 Domain 是否合法。只有校验通过,浏览器才会保存该 cookie,并在后续匹配该域和路径的请求中自动携带。
如果 Set-Cookie 没有写 Domain 属性,这个 cookie 会成为 host-only cookie,只属于当前响应对应的精确主机。例如用户访问 login.example.com,后端不设置 Domain,那么 cookie 只会发给 login.example.com,不会发给 www.example.com 或 api.example.com。这个默认行为更安全,能减少子域之间不必要的 cookie 暴露。
如果后端希望多个子域共享登录态,可以设置 Domain 为合法父域,例如 Domain=example.com。这样在 www.example.com、api.example.com、login.example.com 等子域发起请求时,浏览器都可能携带该 cookie。过去常见写法是 Domain=.example.com,现代浏览器通常会忽略最前面的点,Domain=example.com 与 .example.com 在语义上基本等价。
后端不能把 cookie 设置到任意域名。浏览器会要求 Domain 必须是当前请求主机本身或其父域,且不能是公共后缀。例如 api.example.com 可以设置 Domain=example.com,但不能设置 Domain=other.com,也不能设置 Domain=com。这个限制是为了避免一个网站给另一个网站种 cookie,或者给顶级域污染所有站点。
Path 与 Domain 经常被混淆。Domain 决定哪些主机可以收到 cookie,Path 决定同一主机下哪些 URL 路径可以收到 cookie。例如 Domain=example.com; Path=/admin 表示 example.com 及其子域中,路径以 /admin 匹配的请求才会携带。Path 不是安全边界,不能用它替代权限控制,因为同站页面仍可能通过请求行为间接影响这些 cookie。
在跨站请求中,Domain 只是 cookie 是否匹配目标域的条件之一,并不保证浏览器一定携带 cookie。现代浏览器还会检查 SameSite 属性。若前端从 a.com 请求 api.example.com 并希望携带 cookie,通常需要 cookie 设置 SameSite=None; Secure,同时前端请求启用 credentials,后端 CORS 响应也要允许凭证。
实际系统中不应默认把登录 cookie 放到顶层父域。父域 cookie 虽然方便多个子域共享登录态,但任何被纳入该父域的子系统一旦存在漏洞,都可能影响整个域下的登录态。更稳妥的做法是按业务边界拆分域名和 cookie,必要时通过统一认证中心、短期票据或服务端会话交换来完成跨子域登录。
在现代浏览器语义里,Domain 前面的点通常已经没有实质区别,Domain=.example.com 和 Domain=example.com 都表示允许 example.com 及其子域匹配。需要记住的是,不写 Domain 才是明显不同的情况:不写会生成 host-only cookie,只绑定当前精确主机。
不能。浏览器会校验 Set-Cookie 的 Domain 是否属于当前响应所在主机的合法范围。比如当前响应来自 api.example.com,服务端不能设置 Domain=baidu.com 或 Domain=other.com。即使响应头里写了,浏览器也会拒绝保存。
com、net、co.uk 这类公共后缀不属于某个具体站点。如果允许设置,任何站点都可能污染大量无关域名的 cookie,破坏浏览器同源隔离和站点边界。因此浏览器会依据公共后缀规则拒绝这类 Domain。
常见原因是只设置了 Domain,却没有满足跨站凭证条件。跨站请求通常还需要 cookie 带 SameSite=None; Secure,前端请求配置 credentials,服务端 CORS 返回明确的允许源和允许凭证。任意一个条件不满足,浏览器都可能不发送 cookie。
不会。HttpOnly 的作用是禁止前端 JavaScript 通过 document.cookie 读取或修改该 cookie,从而降低 XSS 窃取风险。它不影响浏览器在匹配 Domain、Path、Secure、SameSite 等规则后,把 cookie 自动放入请求头。