【问题标题】:Safari 13+ iframe blocks CORS cookiesSafari 13+ iframe 阻止 CORS cookie
【发布时间】:2020-04-30 13:06:33
【问题描述】:

Safari 不允许您在与父域不同的域的 iframe 中设置 cookie,该死的服务器端 CORS 标头。

澄清一下:用户在 domainA.com 上。 domainB.com 的 iframe 已打开, 并尝试在 domainB.com 内对用户进行身份验证 框架。 Set-Cookie 标头从 domainB.com iframe 内的服务器返回,包含所有必需的标头,但 Safari 不会在后续调用中将其发回。

一个旧的解决方法是从 iframe 提交表单,并在响应中设置 cookie。我猜他们喜欢用户点击某些东西来提交表单的事实。您必须轮询 cookie 以查看响应何时返回,因为表单提交没有回调,并且在 HttpOnly cookie 的情况下您不能,但是嘿,它起作用了!直到没有。

然后,最近的解决方法是将用户重定向到全新窗口/标签中的 iframe 域,在那里设置一个随机 cookie,从那一刻起,该子域在 iframe 中是“受信任的”。同样,它需要单击才能打开新的窗口/标签,甚至还有新标签打开的视觉指示。很多安全性,这样的标准。

现在,从 Safari 13 开始 - 不再有解决方法。没有更安全的 iframe cookie 设置 ????

任何其他身份验证方案都不适合我们(例如 Auth-X 标头)。我们需要使用 HttpOnly 安全 cookie,因为我们不希望 javascript 客户端以任何方式访问该令牌。

需要明确的是,在任何其他浏览器上一切都很好。

Relevant WebKit Bugzilla

有人有什么建议吗?

编辑:

感谢@tomschmidt 的链接,这似乎是正确的方向。 我尝试使用 Apple 的 Storage Access API,但不幸的是,虽然我确保在使用 API 初始化我的登录逻辑之前请求访问:

requestStorageAccess = async() => {
    return new Promise(resolve => {
      //@ts-ignore
      document.requestStorageAccess().then(
        function () {
          console.log('Storage access was granted');
          resolve(true);
        },
        function () {
          console.log('Storage access was denied');
          resolve(false);
        }
      );    
    });
  }


const storageAccessGranted = await requestStorageAccess();
console.log(storageAccessGranted) // prints 'true'
await login();

不过,在 /login API 响应中收到的 cookie 不会在随后的 API 调用中发送:(

编辑 2(2021 年 5 月):

Safari 14 添加了另一个重大变化:

https://webkit.org/blog/11545/updates-to-the-storage-access-api/

去苹果去吧!你让我们想起了 IE6。

【问题讨论】:

  • 确保仅在与 iframe 进行显式交互时触发,例如 onclick。
  • 是的,我就是这样做的。查看我链接到的 webkit bugzilla 问题,我猜这是 Safari 端的实际错误:/
  • 问题不在于没有发送cookies。如果您请求存储访问,现有的 cookie 将发送到服务器。问题是根本没有存储任何新的 cookie,因此它们不会被发送。
  • @MattCosentino 是的,这就是我的意思 - “在 /login API 响应中收到的 cookie”是在 Set-Cookie 标头响应中发送回 iframe 域的新 cookie,但下一次调用来自 iframe 域的请求中不包含这些 cookie。所以是的,更正确的说法是问题的根源是在这种情况下没有新的 cookie 存储在浏览器中。
  • 在最近的更改之后如何解决这个问题有什么想法吗?我浏览了您共享的链接,但是当我使用 document.hasStorageAccess() 时,我的浏览器抱怨它不是一个函数。

标签: javascript cookies iframe safari cors


【解决方案1】:

我想我可能已经找到了解决方案:Apple 的 Storage Access API: https://webkit.org/blog/8124/introducing-storage-access-api/

【讨论】:

  • 嘿,谢谢你的想法,但恐怕它没有成功(查看我的答案编辑)
  • 我在使用 safari 13 时也遇到了同样的问题。有什么解决方法吗?
  • 您可以在首选项->隐私中禁用“防止跨站点跟踪”
【解决方案2】:

因此,只要新窗口正在存储您要存储的 cookie,解决方法仍然有效。 iframe 仍然无法存储它自己的 cookie。就我而言,我只需要会话 id cookie。因此,当用户授予存储访问权限时,我会打开一个小弹出窗口。它获取并存储会话 ID cookie,关闭并重新加载 iframe。然后 iframe 可以访问会话 id cookie 并在后续请求中发送它。我认为这只是暂时的,看起来他们将来某个时候会从弹出窗口中删除存储访问。也许到那时他们会修复 iframe 无法存储 cookie。

【讨论】:

  • Matt,我使用了一个类似的带有弹出窗口的解决方案,它适用于桌面 Safari 13.1,但在 iPad Safari 13.4 上测试它不起作用。你能在 iPad 上完成这项工作吗?谢谢
  • HI Matt,您可以在其中打开 iframe 代码或主页中的弹出窗口。我也可以有一些示例代码,
  • 我们有任何示例代码吗?
【解决方案3】:

只需转到首选项command + , --> 隐私并取消选中防止跨站点跟踪

【讨论】:

  • 那是用户端的解决方案。问题是我们没有跟踪,但 Safari 是如此严格,以至于它对待我们就像我们在做一样(我们和成千上万的其他合法应用程序,最近的变化伤害了我们)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 2016-04-06
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多