无名草
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9

前言
“CORS”——跨域资源共享。 CORS 是浏览器的协议和安全标准,有助于维护网站的完整性并防止未经授权的访问。
它使浏览器中运行的 JavaScript 能够连接到 API 和其他 Web 资源,例如来自多个不同提供商的字体和样式表。
什么是 CORS?
CORS 是浏览器实现的安全标准,它使浏览器中运行的 脚本 能够访问位于 浏览器域之外 的资源。
CORS 发挥作用的浏览器获取资源的场景:
(1)通过调用 google 的 Map API 在域 xyz.com 中托管的 HTML 或单页应用程序中显示用户位置的地图, https://maps.googleapis.com/maps/api/js。
(2)通过调用 Twitter API 在域 xyz.com 中托管的 HTML 中显示来自公共 Twitter 句柄的推文,https://api.twitter.com/xxx/tweets/xxxxx 。
(3) 在来自远程域的域 xyz.com 中托管的 HTML 中使用诸如 Typekit 和 Google Fonts 之类的网络字体。
放宽同源政策
CORS 策略的作用是 维护网站的完整性并防止未经授权的访问。
CORS 协议被定义为放宽浏览器用来保护其资源的称为同源策略 (SOP) 的默认安全策略。
同源策略允许浏览器仅从与浏览器同源的服务器加载资源。
SOP 是在 Web 的早期定义的,结果证明对于我们经常需要从多个来源获取不同类型资源的新时代应用程序来说限制太多。
CORS 协议由所有现代浏览器实现,以允许对位于浏览器源之外的资源进行受控访问。
什么是源?
CORS中的 Origin由三个元素组成:
URL 方案(协议):例如 http 或 https;
主机(域名):类似 www.xyz.com;
端口:如8000或80(默认 HTTP 端口)。
浏览器如何实现 CORS 策略
CORS 协议仅由浏览器强制执行。浏览器通过向跨域服务器发送一组 CORS 标头来执行此操作,该服务器在响应中返回特定标头值。根据跨域服务器响应中返回的标头值,浏览器通过在浏览器控制台中显示 CORS 错误来提供对响应的访问或阻止访问。
使用基于头的 CORS 协议
当从网页中发出获取资源的请求时,浏览器会检测请求是向源服务器还是跨源服务器,如果是跨源服务器,则应用 CORS 策略。
浏览器向
Origin
跨域服务器发送一个以请求命名的标头。跨域服务器处理此请求并发送回Access-Control-Allow-Origin
响应中命名的标头。浏览器检查
Access-Control-Allow-Origin
响应中标头的值,并仅在Access-Control-Allow-Origin
标头的值Origin
与请求中发送的标头相同时才呈现响应。跨域服务器还可以使用通配符
*
作为Access-Control-Allow-Origin
标头的值来表示与Origin
请求中接收到的标头值的部分匹配。
CORS 失败
CORS 失败会导致错误,但出于安全原因,浏览器无法获得有关错误的详细信息,因为攻击者可以从错误消息中获取提示来定制后续攻击以增加成功的机会。
了解错误的唯一方法是查看浏览器的控制台以获取错误的详细信息,通常采用以下形式:
Access to XMLHttpRequest at 'http://localhost:8000/orders' from origin 'http://localhost:9000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
浏览器控制台中显示的错误伴随着错误“原因”消息。根据实现,原因消息可能因浏览器而异。
浏览器发送的 CORS 请求类型
浏览器根据我们希望对跨域服务器中的资源执行的操作类型来确定要发送到跨域服务器的请求类型。
浏览器可以向跨域服务器发送 三种 类型的请求:
simple
preflight
requests with credentials
简单的 CORS 请求(GET、POST 和 HEAD)
浏览器会发送简单的请求来执行它认为安全的操作,例如
GET
获取数据的HEAD
请求或检查状态的请求。如果满足以下条件之一,则浏览器发送的请求很简单:
- HTTP请求方法是
GET
,POST
,或HEAD
- HTTP 请求包含一个 CORS 安全列表标头:
Accept
、Accept-Language
、Content-Language
、Content-Type
。 - 当 HTTP 请求包含
Content-Type
标头时,它包含作为它的值:application/x-www-form-urlencoded
,multipart/form-data
, 或text/plain
- 没有在任何 XMLHttpRequestUpload 对象上注册事件侦听器
ReadableStream
请求中没有使用对象
浏览器在添加
Origin
header后将简单请求作为类似于Same Origin请求的普通请求发送,Access-Control-Allow-Origin
返回响应时浏览器检查header。只有当
Access-Control-Allow-Origin
标头的值Origin
与请求中发送的标头的值匹配时,浏览器才能读取和呈现响应。该Origin
标头包含请求的源来源。
预检请求
与简单请求相反,浏览器会发送预检请求,以执行旨在更改跨源服务器中任何内容的操作,例如
PUT
更新资源的 HTTP方法或DELETE
删除资源的 HTTP方法。这些请求不被认为是安全的,因此 Web 浏览器首先通过在将实际请求发送到跨域服务器之前首先发送预检请求来确保允许跨域通信。不满足简单请求标准的请求也属于这一类。
预检请求是一种
OPTIONS
由浏览器自动发送到跨域服务器的 HTTP方法,以检查跨域服务器是否允许实际请求。随着预检请求,浏览器发送以下标头:
- Access-Control-Request-Method:此标头包含在发出实际请求时将使用的 HTTP 方法。
- Access-Control-Request-Headers:这是将与请求一起发送的标头列表,包括任何自定义标头。
- Origin:包含请求的源源的源头,类似于简单请求。
如果该
OPTIONS
方法的结果是无法发出请求,则不会向跨域服务器发送实际请求。预检请求完成后,
PUT
发送带有 CORS 标头的实际方法。
由于同源策略导致的 CORS 错误
如果我们在跨域服务器中运行这些应用程序而没有任何额外的配置(设置 CORS 标头),我们将在浏览器控制台中收到一个 CORS 错误,如下所示:
这是由于同源策略限制访问跨域导致的错误。
总结
- CORS 是浏览器实现的安全协议,允许我们访问来自不同来源的资源。
- CORS请求有三种类型:
Simple
,Preflight
,和Request with Credentials
。 - 简单请求用于执行安全操作,如 HTTP
GET
方法。 - 预检请求用于执行具有 副作用 的操作。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)