跨源资源共享(CORS)
这里来聊聊跨源资源共享CORS(Cross Origin Resouce Share)。
开局一张图,很多人错误理解跨源资源共享就是浏览器在访问服务器A(domain-a.com)获取的资源如果包含跨源服务器B(domain-a.com)资源的时候那么此时就需要跨源资源共享,所以我们需要配置我们的访问控制策略Access-Control-Allow-Origin 运行所有站点访问。
但是为什么这里跨源资源共享是被服务器B控制的?
原来这里这里跨源资源共享是浏览器用来保护服务器B的,防止服务器A加载的资源伪造一个请求,但是此时浏览器已经记住了服务器B的Cookie认证,从而完一次对服务器B的攻击,这就是跨源请求伪造(Cross-site request forgery)。
假如浏览器没有CORS,会是怎样?我们需要举个栗子:
用户在浏览如上购物网站B(domain-b.com),此时已经完成认证,浏览器会自动将记住服务器B的Cookie,方便你继续浏览。此时我们在新的标签页开始浏览网页访问服务器A(domain-a.com),服务器A加载的JavaScript可以直接对服务器B发起了一次请求获取了你的购物信息。
所以此时服务器B的同源策略就一项非常重要的安全措施。
浏览器有CORS又会是怎样?
简单请求
对于如上的跨源资源请求浏览器会区分是简单请求还是非简单请求。什么是简单请求?
使用下列方法之一:
GET
HEAD
POST
仅存在如下头部字段:
Accept
Accept-Language
Content-Language
Content-Type
(需要注意额外的限制)
Content-Type
的值仅限于下列三者之一:
text/plain
multipart/form-data
application/x-www-form-urlencoded
对于简单请求浏览器直接发起请求,并且带上头部字段Origin
,从而把访问控制决策直接交给服务器B,服务器B返回Access-Control-Allow-Origin: xxx
字段指示该资源可以被是否可以被跨源访问。
预检请求
而对于非简单请求又怎么办呢?浏览器会慎之又慎,先发起一次预检请求(OPTIONS),确认该服务器A被允许跨站点访问后再进行访问。
预检请求会获取如下(但不限于)信息。有了这些信息,浏览器就可以判断是否进行跨源请求了。
- Access-Control-Allow-Methods指示其支持的HTTP请求方法。
- Access-Control-Allow-Origin当前站点支持跨源资源共享站点。
- Access-Control-Max-Age 预检请求的最大缓存时间。
结论
那么对于服务器B如何控制跨源策略呢?
- 首先需要进行开启跨源请求伪造过滤(CORF)。
- 理论上默认是不支持任何跨源访问的,确实需要也应该是白名单机制,避免通配符。
origin 和referer
- 所以正常访问的跨站点的链接跳转都会带上referer,不管是同源和跨源,包含完整URL。
- 只有跨源请求的时候才会带上origin,只包含域名,不带URL。
还不快抢沙发