使用来自子域的请求发送 cookie
Posted
技术标签:
【中文标题】使用来自子域的请求发送 cookie【英文标题】:Sending cookie with request from subdomain 【发布时间】:2021-01-21 06:54:31 【问题描述】:我们有以下配置:
testing.parentdomain.com
当您访问此域并创建一个购物篮时,我们会创建一个 cookie 来存储购物篮的价值。 cookie域设置为.testing.parentdomain.com
,是Httponly,路径为/
我们有一个想要访问 cookie 的上述子域。 subdomain.testing.parentdomain.com
此子域调用父域上的端点,例如:testing.parentdomain.com/basketData
。此调用是返回 JSON 的 GET 请求。
问题 问题是子域在发出请求时似乎没有发送 cookie 值,因此我们没有得到预期的响应。
尝试 查看其他问题,我们尝试了 CORS 和凭据更改。 作为补充说明,我们将以下 JS 与 webpack/babel 捆绑在一起。 我们的请求来自 AJAX,如下所示:
$.ajax(
url: url,
type: 'GET',
xhrFields:
withCredentials: true
,
crossDomain: true
)
服务器为子域和允许凭据设置了 CORS。在响应中,我们可以看到这些被返回。 访问控制允许凭据:true access-control-allow-origin:上面的子域
是否有任何原因导致 cookie 没有随请求一起发送到父域?我们已经在服务器端响应中注销了 cookie,但它们并不像我们预期的那样存在。
请求标头
:authority: testing.parentdomain.com :method: 获取 :path: /basket/data/ :scheme: https 接受:/ 接受编码:gzip、deflate、br 接受语言:en-GB,en;q=0.9,en-US;q=0.8 来源:https://subdomain.testing.parentdomain.com 推荐人:https://subdomain.testing.parentdomain.com/ sec-fetch-dest: 空 秒获取模式:cors sec-fetch-site: 同一站点 用户代理:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/86.0.4240.111 Safari/537.36
响应标头
访问控制允许凭据:true 访问控制允许方法:GET、PUT、POST、DELETE、HEAD、OPTIONS 访问控制允许来源:https://subdomain.testing.parentdomain.com 缓存控制:无缓存,无存储 内容长度:2238 内容类型:应用程序/json;字符集=utf-8 日期:格林威治标准时间 2020 年 11 月 3 日星期二 20:39:36 过期:-1 编译指示:无缓存 服务器:Microsoft-IIS/10.0 设置cookie:AWSALB=N0bcThdgRFzrSfQVNIsffgsvY6T/y2Bp47RZJCueeSLOS7eEjo0AThiElXmww6fy2eynRyyt8gAB8di/Mqy1x+Ds8Ig1TumKkWnQiFvIkoELI/rEYYgyUxbEtUI4;到期=格林威治标准时间 2020 年 11 月 10 日星期二 20:39:36;路径=/ 设置cookie:AWSALBCORS=N0bcThdgRFzrSfQVNIsffgsvY6T/y2Bp47RZJCueeSLOS7eEjo0AThiElXmww6fy2eynRyyt8gAB8di/Mqy1x+Ds8Ig1TumKkWnQiFvIkoELI/rEYYgyUxbEtUI4;到期=格林威治标准时间 2020 年 11 月 10 日星期二 20:39:36;路径=/;相同站点=无;安全 状态:200 严格传输安全:max-age=31536000; 变化:起源 x-content-type-options: nosniff x-frame-options: SAMEORIGIN x-机器人标签:无索引 x-ua 兼容:IE=edge x-xss-保护:1;模式=块
【问题讨论】:
服务器没有记录 cookie,好的。您是否检查过客户端浏览器上是否设置了 cookie?您是否检查过 GET 请求(来自客户端浏览器)以检查 cookie 是否在标头中?这些检查将有助于区分问题是将 cookie 发送到服务器还是在客户端设置 cookie。可能你已经做了这个检查,你能确认一下吗?谢谢 是的,我们已经确认 cookie 设置正确。 cookie 不随请求一起发送和/或响应未接收到。是的,我们正在注销服务器上的请求 cookie,以便能够确定这一点 如果您在浏览器控制台中看到带有标头的 http 请求和响应,这将很有用。 我非常同意@Lety 是否可以在 cookie 中只保留父域? 【参考方案1】:即使您从子域调用主域,这也被视为跨域请求。
来自RFC 6454 的引述符合“起源”术语的条件:
问:为什么要使用完全限定的主机名,而不仅仅是“top- 级”域?
答:虽然 DNS 具有分层委托,但信任 主机名之间的关系因部署而异。例如,在 许多教育机构,学生可以在https://example.edu/~student/ 托管内容,但这并不意味着文档 由学生创作的作品应属于同一来源(即, 位于相同的保护域中)作为用于管理的 Web 应用程序 成绩托管在https://grades.example.edu/。
所以你所做的所有事情确实是需要让它发挥作用:
access-control-allow-credentials: true
access-control-allow-origin: subdomain.testing.parentdomain.com
(不是通配符)
请求中的withCredentials: true
在这种情况下不需要SameSite=None
cookie 属性,因为从子域到同一域的另一个子域的请求被视为“同一站点”(Source)。
所以只需检查所有设置是否正确,它应该可以正常工作。
【讨论】:
我已经更改了 cookie 以确保它是安全的并且 SameSite=None 并且发生了同样的问题。似乎 cookie 没有随请求一起发送,因为在 Postman 中测试时 GET 工作正常。当从网页发出请求以获取更多信息时,我添加了 Chrome 中显示的响应/请求标头 网站/API 是通过 HTTPS 提供的吗? 是的,两者都通过 https 服务 这是对该问题的最完整答案。我们添加了所需的标头,但问题仍然存在,但是,这是由我们的构建过程中的错误引起的,这意味着 withCredentials 没有被推送到构建的 JS 文件中。一旦我们添加了这个,一切都开始按我们预期的那样工作。 感谢您指出这一点,我已经编辑并添加了源代码【参考方案2】:在你的问题开始时你说:
cookie域设置为
.testing.parentdomain.com
但在记录的服务器响应中:
set-cookie: AWSALBCORS=N0bcThdgRFzrSfQVNIsffgsvY6T/y2Bp47RZJCueeSLOS7eEjo0AThiElXmww6fy2eynRyyt8gAB8di/Mqy1x+Ds8Ig1TumKkWnQiFvIkoELI/rEYYgyUxbEtUI4; Expires=Tue, 10 Nov 2020 20:39:36 GMT; Path=/; SameSite=None; Secure
Domain=.testing.parentdomain.com;
参数明显丢失。
我不知道您使用哪种编程语言来设置 cookie,但我强烈建议您在服务器响应中检查用于设置 cookie 的调用。
【讨论】:
你好丹尼尔。来自服务器的响应此时没有设置 cookie,cookie 是在其他工作正常的阶段之前设置的。 cookie 设置在主域上,然后从子域访问我们称为主域上的端点,这是不发送 cookie 的时候 对不起@StuartM,有意义的服务器响应是设置cookie的;您粘贴了服务器响应,我认为这是对这个主题感兴趣的人。您能否分享设置 cookie 的服务器响应?对不工作的服务器调用的服务器响应对于解决此问题的目的是无用的。 这是一个 ASP.net 后端,我可以看到 cookie 是使用 editThisCookie 设置的。我可以看到值是正确的,路径是'/',域是'.testing.parentdomain.com',它是Secure and HTTPOnly。 对不起@StuartM,但没有a)用于设置cookie的客户端调用的转储; b) 设置 cookie 的服务器响应 - 即调用 a - 的服务器响应; c) 缺少 cookie 的客户端请求;我帮不了你 顺便说一下,检查 cmets 到你的问题 @StuartM ,我看到 Lety 也在问同样的转储。以上是关于使用来自子域的请求发送 cookie的主要内容,如果未能解决你的问题,请参考以下文章