了解 CORS

Posted

技术标签:

【中文标题】了解 CORS【英文标题】:Understanding CORS 【发布时间】:2014-11-08 19:29:03 【问题描述】:

我一直在网上寻找有关 CORS 的信息,我想确认我所做的是否是,它实际上是什么。

下面提到的是一个完全虚构的场景。

我将举一个普通网站的例子。假设我的 html 页面有一个带有文本字段名称的表单。提交后,它将表单数据发送到myPage.php。现在,内部发生的是,服务器将请求连同文本字段一起发送到www.mydomain.com/mydirectory/myPage.php。现在,服务器看到请求是从同一个域/端口/协议触发的

问题 1。服务器如何知道所有这些细节。它从哪里提取所有这些细节?

尽管如此,由于请求来自同一个域,因此它会为 php 脚本提供服务器并返回所需的任何内容。

现在,为了论证,假设我不想手动填充文本字段中的数据,而是想以编程方式完成。我所做的是,我使用 javascript 创建了一个 html 页面,并触发了一个 POST 请求以及参数(即 textField 的值)。现在,由于我的请求不是来自任何域,因此服务器忽略了我的请求的服务。我得到跨域错误?

同样,我也可以编写一个 Java 程序,它利用 HTTPClient/Post 请求并做同样的事情。

问题 2:这就是问题所在吗?

现在,CORS 为我们提供的是,服务器会说“任何人都可以访问 myPage.php”。 来自enable cors.org,它说

对于简单的 CORS 请求,服务器只需要在其响应中添加以下标头: 访问控制允许来源:*

现在,客户端究竟要如何处理这个标头。如,客户端无论如何都想调用服务器上的资源,对吗?应该由服务器自行配置是否要接受,并采取相应的行动。

问题 3:将标头发送回客户端(谁已经向服务器发出请求)有什么用?

最后,我不明白的是,我正在为我的 android 应用程序构建一些 RESTful 服务。现在,假设我有一个 POST 服务www.mydomain.com/rest/services/myPost。我的 Tomcat 服务器在我的本地机器上托管这些服务。

在我的 android 应用程序中,我只是调用此服务,然后返回结果(如果有)。在这种情况下,我到底在哪里使用了 CORS。这是否属于不同类别的服务器调用?如果是,那么究竟如何。

此外,我检查了Enable Cors for Tomcat,它说我可以在我的动态 Web 项目的 web.xml 中添加一个过滤器,然后它将开始接受它。

问题 4:这就是我的 android 设备调用我的网络服务的原因吗?

谢谢

【问题讨论】:

【参考方案1】:

    首先,跨域检查是由浏览器进行的,而不是服务器。当 JavaScript 向其源以外的服务器发出XmlHttpRequest 时,如果浏览器支持 CORS,它将初始化一个 CORS 进程。否则,请求将导致错误(除非用户故意降低浏览器安全性)

    当服务器遇到Origin HTTP 头时,服务器会判断它是否在允许的域列表中。如果不在列表中,则请求将失败(即服务器将发送错误响应)。

对于数字 3 和 4,我认为您应该分别提出问题。否则这个问题会变得太宽泛。而且我认为如果您不删除它,它会很快接近。

关于CORS的解释,请看程序员的这个回答:https://softwareengineering.stackexchange.com/a/253043/139479

注意:CORS 更像是一种约定。它不保证安全。您可以编写无视相同域策略的恶意浏览器。它将执行从任何站点获取的 JavaScript。您还可以使用任意 Origin 标头创建 HTTP 标头,并从任何实现 CORS 的第三方服务器获取信息。 CORS 仅在您信任您的浏览器时才有效。

【讨论】:

支持 CORS 的 API 是否应该执行请求,即使 CORS Origin 不是可识别的?我已经看到了 CORS 的实现,其中始终执行请求,但是响应中的 CORS 标头仅由服务器在识别出 Origin 时设置。不确定这是否是好的设计? @Josh 我不确定。我们必须仔细查看规格。我想这需要一个全新的问题。 @Krumia:实际上,只有当您信任您的浏览器时,CORS 才有效:它是同源策略。 SOP是保障机制,CORS是允许异常的便捷方式。您可以随心所欲地信任您的浏览器,但如果您的家庭银行网站将 Access-Control-Allow-Origin 设置为 *,那么您将度过一段糟糕的时光! @sampathsris - 错误响应是什么意思?我正在使用基本的 express 服务器尝试 cors,发送的响应是 200(而浏览器抛出错误,这表明我的有效负载仍然提供给坏域的浏览器)【参考方案2】:

对于问题3,你需要了解两个站点和客户端浏览器之间的关系。正如 Krumia 在他们的回答中提到的那样,这更像是请求中三个参与者之间的约定。

我最近posted an article 更详细地介绍了 CORS 握手的工作原理。

【讨论】:

【参考方案3】:

好吧,我不是安全专家,但我希望我能一口气回答这个问题。

如果启用了 CORS,那么服务器只会询问浏览器您是否从 [xyz.com] 调用请求?如果浏览器说是,它会显示结果,如果浏览器说不是,它来自 [abc.com],它会抛出错误。

所以 CORS 依赖于浏览器。这就是浏览器在实际请求之前发送预检请求的原因。

【讨论】:

以上是关于了解 CORS的主要内容,如果未能解决你的问题,请参考以下文章

了解 AJAX CORS 和安全注意事项

网络知识补习❄️| 由浅入深了解HTTP跨源资源共享(CORS)

了解页面响应

跨域-Nginx-CORS配置

不允许使用 CORS 405 方法

同源策略与 CORS 的用处