最佳方法:Access-Control-Allow-Origin Multiple Origin Domains
Posted
技术标签:
【中文标题】最佳方法:Access-Control-Allow-Origin Multiple Origin Domains【英文标题】:Best method: Access-Control-Allow-Origin Multiple Origin Domains 【发布时间】:2014-10-08 04:18:50 【问题描述】:这个问题以前在这里被问过,并给出了一系列很好的答案,主要是: Access-Control-Allow-Origin Multiple Origin Domains?
但是,就应采用的批准方法而言,解释似乎存在差距。通读 W3 文档,我们发现在我看来是指导冲突。
首先,我们在许多先前的答案中看到给出的答案是正确的方法,这表明主机服务器必须动态回显给定的“来源”,如果它出现在预定义的“白名单”。 http://www.w3.org/TR/cors/#resource-implementation
然而,许多使用的答案和方法也暗示了一个空格分隔的列表,它也可以用作传递多个“起源”以允许的方法。如果我们看一下http://www.w3.org/wiki/CORS_Enabled 的另一篇 W3 文档,我们会在页面的第一部分看到这样的示例:
Access-Control-Allow-Origin: http://example.com:8080 http://blah.example.com http://foo.example.com
在这两种方法中,我同样很乐意将其中任何一种合并,但是可能会有大量 URL 需要被列入名单,所以我想确保我第一次这样做是正确的。如果有人对上述两种方法有任何见解,我将非常感激听到您在选择中做出的决定,并且如果有我可能错过的推荐方法的明确指南。
【问题讨论】:
【参考方案1】:有关此的文档似乎暗示它允许使用空格分隔列表的多个来源,但这并不是它的实际含义。以下是我可以收集到的最明确的答案:只要您允许,Access-Control-Allow-Origin
标头的值应该与 Origin
标头相同。
您将其发送回客户端的原因不是白名单,因为从技术上讲,客户端可以发送以空格分隔的来源列表,以便服务器可以验证请求。源列表的目的是因为请求可能来自多个源(即请求被重定向到跨域)。 A test suite 可以通过不同的重定向可能性轻松观察这种行为,即使从未生成空格分隔列表(至少由 Firefox 生成)。
这在您提供的第一个linked W3C document 下方有说明:
Access-Control-Allow-Origin 标头指示是否可以通过在响应中返回 Origin 请求标头的值、“*”或“null”来共享资源。 ABNF:
Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" origin-list-or-null | “*”
在实践中,origin-list-or-null 产生式受到更多限制。它不允许以空格分隔的来源列表,而是单个来源或字符串“null”。
又是the definition of the origin list。此外,它还显示如果您确实希望允许字符串“null”作为来源,那么无论如何它都无法嵌入到来源列表中。
所以坚持使用基于客户端的Origin
标头动态生成的标头以及它是否与您的白名单匹配。
【讨论】:
考虑到客户端的原始标头可能被客户端操纵,是否存在任何安全后果? 原始标头旨在保护用户免受恶意网站的侵害。例如,如果 mywebsite.com 向 mybank.com 发送了 AJAX 请求,则默认情况下它应该被拒绝。如果用户想要修改这种行为,那么他们当然可以做任何他们想做的事情。用户可以轻松地打开他们的浏览器控制台,向该网站发送请求,并将响应用于他们打开的任何其他页面。但是,任何符合 HTTP 的网络浏览器都不会让网站自动执行此操作。 有谁知道,我如何验证客户提供的来源列表?所有条目都应该匹配允许的域列表还是至少一个? 根据规范 6.2.2,用户代理不应至少为航班请求生成多个来源:“Origin 标头只能包含单个来源,因为用户代理不会遵循重定向。” @SergeyMashkov 安全总比后悔好;您不妨验证整个列表。似乎起源列表是如此罕见,以至于它几乎总是一个单一的起源。如果您遇到任何问题,则可以考虑添加其他允许的来源或更改行为。【参考方案2】:如果您需要允许包含特定单词“示例”的来源,您可以在您的 apache vhost 中使用以下配置。
SetEnvIf Origin "^((?:https?:\/\/)?(?:[^@\n]+@)?(?:www.)?.example?.*)" REFERER=$0
Header always set Access-Control-Allow-Origin %REFERERe env=REFERER
这将满足以下一些 Origin 条件:
http://abc.bcd.example.com
https://www.example.in
http://abcdexample.com
many more
您可以根据需要调整上述正则表达式。
【讨论】:
这个正则表达式需要工作......它与您提供的任何示例都不匹配,但它与lexampl.lol
之类的内容匹配。如果要显式匹配句点,则需要对句点进行转义,如果要匹配子域(加上分组外的星号),则需要使用某种通配符或字符类,并且您可能应该明确说明您想要哪些 TLD匹配。以上是关于最佳方法:Access-Control-Allow-Origin Multiple Origin Domains的主要内容,如果未能解决你的问题,请参考以下文章
通过 Axios 从 Javascript 代码发布到 .net Web Api 时,Access-Control-Allow Headers CORS 错误