对象存储设置跨域资源共享

对象存储跨域资源共享
跨域访问,是浏览器出于安全考虑而设置的一个限制,即同源策略。举例说明,当 A,B 两个网站属于不同的域时,如果来自于 A 网站的页面中的 JavaScript 代码希望访问 B 网站的时候,浏览器会拒绝该访问。然而,在实际应用中,经常会有跨域访问的需求。

跨域资源共享是 HTML5 提供的标准跨域解决方案,具体的CORS规则可以参考 W3C CORS规范。
CORS 是一个由浏览器共同遵循的一套控制策略,通过HTTP的Header来进行交互。浏览器在识别到发起的请求是跨域请求的时候,会将Origin的Header加入HTTP请求发送给服务器,如"Origin:http://www.a.com"。服务器端接收到这个请求之后,会根据一定的规则判断是否允许该来源域的请求,如果允许的话,服务器在返回的响应中会附带上Access-Control-Allow-Origin这个Header,内容为www.a.com来表示允许该次跨域访问。如果服务器允许所有的跨域请求的话,将Access-Control-Allow-Origin的Header设置为*即可,浏览器根据是否返回了对应的Header来决定该跨域请求是否成功,如果没有附加对应的Header,浏览器将会拦截该请求。

以上描述的仅仅是简单情况,CORS规范将请求分为两种类型,一种是简单请求,另外一种是带预检的请求。预检机制是一种保护机制,防止资源被本来没有权限的请求修改。浏览器会在发送实际请求之前先发送一个OPTIONS的HTTP请求来判断服务器是否能接受该跨域请求。如果不能接受的话,浏览器会直接阻止接下来实际请求的发生。
预检请求会附带一些关于接下来的请求的信息给服务器,主要有以下几种:
 
Origin:请求的源域信息
Access-Control-Request-Method:接下来的请求类型,如POST、GET等
Access-Control-Request-Headers:接下来的请求中包含的用户显式设置的Header列表
服务器端收到请求之后,会根据附带的信息来判断是否允许该跨域请求,信息返回同样是通过Header完成的:
 
Access-Control-Allow-Origin:允许跨域的Origin列表
Access-Control-Allow-Methods:允许跨域的方法列表
Access-Control-Allow-Headers:允许跨域的Header列表
Access-Control-Expose-Headers:允许暴露给JavaScript代码的Header列表
Access-Control-Max-Age:最大的浏览器缓存时间,单位s。

CORS主要使用场景
CORS使用一定是在使用浏览器的情况下,因为控制访问权限的是浏览器而非服务器。因此使用其它的客户端的时候无需关心任何跨域问题。
使用CORS的主要应用就是在浏览器端使用Ajax直接访问OSS的数据,而无需走用户本身的应用服务器中转。无论上传或者下载。对于同时使用OSS和使用Ajax技术的网站来说,都建议使用CORS来实现与OSS的直接通信。
 
对象存储跨域支持
OSS提供了CORS规则的配置从而根据需求允许或者拒绝相应的跨域请求。该规则是配置在Bucket级别的。详情可以参考PutBucketCORS。
CORS请求的通过与否和OSS的身份验证等是完全独立的,即OSS的CORS规则仅仅是用来决定是否附加CORS相关的Header的一个规则。是否拦截该请求完全由浏览器决定。
当浏览器向MSS发起GET请求,会带一个Origin头部"Origin:http://www.a.com",如果MSS返回的头部没有带"Access-Control-Allow-Origin:http://www.a.com",则浏览器会拒绝接收。MSS采取的策略为当用户发起跨域请求时,如果请求所在的桶没有配置跨域策略,则会直接返回403。
浏览器在上传文件时,会发起一个OPTIONS请求,请求头部"Access-Control-Allow-Method:PUT"。如果没有配置跨域,MSS会返回"Access-Control-Allow-Methods:PUT","Access-Control-Allow-Origin:http://www.a.com",则浏览器才会继续下一步的PUT请求。若没有返回跨域允许的头部,浏览器会停止下一步的PUT操作。
 
GET请求跨域示例
 
当没有对Bucket设置跨域时,如果请求带Origin头部,则会报错:
$ curl -i -H "Origin:http://www.a.com" "http://mtmss.com/v1/mss_9698a7d474484149970fe7f751eb4fc6/cors-test/test.txt"
HTTP/1.1 403 Forbidden
Server: Tengine
Date: Fri, 24 Nov 2017 06:32:25 GMT
Content-Type: text/xml; charset=utf-8
Content-Length: 286
Connection: keep-alive
X-Amz-Id-2: c6c6c11d21f373e51af4b369cc17b7df
X-Amz-Request-Id: 1511505145675747
X-Ms-Trans-Id: 47d571e36a28fbfd2280e9701d9eb96a-1511505145673812
X-Mss-Trace-Id: 310194632421683019
 
<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied. Cors access deny</Message>
  <Resource>Bucket:cors-test,Object:test.txt</Resource>
  <RequestId>1511505145675747</RequestId>
  <HostId>c6c6c11d21f373e51af4b369cc17b7df</HostId>
</Error>
设置跨域,创建一个文件(cors.xml),内容如下:
$ s3cmd setcors cors.xml s3://cors-test
<CORSConfiguration>
   <CORSRule>
       <AllowedOrigin>http://www.a.com</AllowedOrigin>
       <AllowedMethod>*</AllowedMethod>
       <AllowedHeader>*</AllowedHeader>
   </CORSRule>
</CORSConfiguration>
重新执行 curl -i -H "Origin:http://www.a.com" "http://mtmss.com/v1/mss_9698a7d474484149970fe7f751eb4fc6/cors-test/test.txt"
HTTP/1.1 200 OK
Server: Tengine
Date: Fri, 24 Nov 2017 06:26:06 GMT
Content-Type: text/plain
Content-Length: 12
Connection: keep-alive
Access-Control-Allow-Origin: http://www.a.com
ETag: "25a514f4c216f30bdfe1f8a71f1a5882"
Last-Modified: Fri, 24 Nov 2017 06:10:17 GMT
X-Amz-Id-2: ab9f6e23723d423c026c74a02003454f
X-Amz-Request-Id: 1511504766214314
X-Ms-Trans-Id: 34316b4a9e8b747113019eb526974a3c-1511504766215266
X-Mss-Trace-Id: 310199030467814662
x-amz-meta-s3cmd-attrs: uid:551/gname:chenghua/uname:chenghua/gid:551/mode:33204/mtime:1511503806/atime:1511503806/md5:25a514f4c216f30bdfe1f8a71f1a5882/ctime:1511503806
 
hello, mss!

标签

发表评论