无 `Referer:`,无嵌入

你好,

我们在 New ROOT Web Site! - ROOT 使用 Discourse 嵌入 Jekyll,效果非常好!不过,如果浏览器阻止了 Referer: 头,我们就会收到 400 Bad Request 错误。您可以亲自测试:如果切换到 Firefox 的隐私窗口(该模式会阻止发送 Referer),嵌入功能就会失效。Safari 也有类似问题,它似乎对发送 Referer 的限制更严格。

我通过访问 New ROOT Web Site! - Blog - ROOT Forum 进行了交叉验证,在 Firefox 隐私窗口中该请求返回 HTTP 400 错误;随后我手动编辑请求,添加 Referer: https://root.cern/blog/new-web-site/ 后,400 错误就变成了 200 成功响应。

我们已启用“允许嵌入任意来源”选项,且目前只为一个嵌入站点配置了评论功能。请问有什么方法可以让它正常工作吗?

祝好,
Axel

4 个赞

是的,我可以复现这个问题。

有趣的是,在 Firefox 隐私窗口中,嵌入在 https://blog.codinghorror.com/the-cloud-is-just-someone-elses-computer/ 上的评论可以正常工作。问题是否与域名有关?您的博客位于 root.cern,而您的表单位于 root-forum.cern.ch

2 个赞

嗨,Simon,

谢谢你查看这个问题!这很可能与域名差异有关:我猜想浏览器可能会为指向同一域名的请求提供引用来源,但不会为指向不同域名的请求提供。不过,虽然这一点很有趣,但我目前还看不出我们能做些什么来解决这个问题——我们无法将 root.cern 用作论坛域名,而跨域嵌入似乎是一个关键且非常实用的功能……鉴于隐私保护的加强,这项功能是否正面临风险?或者你能想到什么解决办法吗?

我或许可以尝试通过反向代理,将 root.cern/forum 映射到 root-forum.cern.ch。这样一来,嵌入操作就可以像在同一主机上进行一样,同时我们也能保留引用来源……?我稍后再回来 :slight_smile:

祝好,
Axel

2 个赞

你好,

我现在有一个更简单的解决方案。这个问题可能应该在 Embed Discourse comments on another website via Javascript 中被特别指出:

对于跨站点嵌入,在嵌入页面中添加以下任一代码:

  • <meta name="referrer" content="strict-origin">,并将“路径白名单”设置为 /.*(因为不会提供具体路径),或
  • <meta name="referrer" content="no-referrer-when-downgrade">,并设置实际的“路径白名单”。

正如 Referrer-Policy header - HTTP | MDN 中提到的,“浏览器正在努力将默认值改为更严格的策略”,而 Discourse 的跨主机嵌入功能依赖于旧的默认行为。

祝好,
Axel

2 个赞

鉴于从 Chrome 85 开始这将默认成为浏览器标准(Blog  |  Chrome for Developers

我们是否可以接受同时满足以下三个条件的请求:

  • 请求中同时包含 discourseEmbedUrlReferer
  • Referer 设置为 discourseEmbedUrl 的源
  • discourseEmbedUrl 匹配嵌入规则之一

我认为对大多数用户而言,传递 discourseEmbedUrl 是很容易实现的。

提醒一下,Tejas——据我所知,如果没有 meta 标签,Safari 和 Firefox 的隐私模式会完全抑制 Referer 头。你建议的方法可能在 Chrome >= 85 上有效,但添加 meta 标签似乎更稳健、更具通用性,而且我怀疑对于大多数嵌入场景来说,这样做已经足够简单了。