CORS跨域请求

何为跨域请求

若请求的url的协议、域名、端口中的任意一个与当前的url不一样,即为跨域请求。跨域

跨域请求使得页面体验更好,但同时也带来了安全隐患。常见的一种网络攻击叫CSRF(Cross-site request forgery)。它的攻击原理大体以下:浏览器

  1. 用户访问正常网站A,诸如某银行,登陆进去,A生成cookie信息并返回给用户的浏览器
  2. 保持网站A的登陆状态,在同一个浏览器窗口的新tab页进入恶意网站B
  3. B网站的恶意代码被执行,要求跨域请求A网站的某些资源,诸如转帐功能
  4. 浏览器响应该请求,在用户不知情的状况下携带cookie信息,向A发出请求
  5. 网站A根据用户的cookie信息核实用户身份,处理该请求,那么来自网站B的恶意请求被执行

CORS验证机制

基于CSRF等安全隐患,浏览器会限制从脚本发出的跨域请求,虽然安全性更高,页面体验却差了。因而W3C推出了一种跨域的访问验证的机制,即CORS,这种机制支持跨域请求,且跨站数据传输更安全。安全

CORS验证机制须要客户端和服务的协同处理。服务器

客户端处理机制

浏览器会对全部跨域请求进行验证,分为简单请求验证处理和预检请求验证处理。那么对应的就有简单请求和非简单请求之分。cookie

简单请求网络

若一个请求同时知足如下两个条件,那么则为简单请求。app

  • 请求方法为GET或HEAD或POST
  • 请求头中的Content-Type值为application/x-www-form-urlencoded 或 multipart/form-data 或 text/plain

对于简单请求,浏览器直接发送该请求,在同一个请求中做跨域验证。怎么验证呢?在请求头上附上Origin属性,代表这是一个跨域请求。服务器接到请求,根据设定的跨域规则来验证,验证经过,返回Access-Control-Allow-Origin等以Access-Control-开头的响应头以及请求的资源,不然返回403状态码,且不会返回请求的资源。fetch

非简单请求网站

不为简单请求的跨域请求均为非简单请求。url

非简单请求的跨域验证经过一个预检请求来验证,即在发送一个正式的跨域请求以前,发送一个预检请求,用来检查当前网页所在的域名是否在服务器的许可名单中以及可以使用哪些请求方法,请求头字段。

预检请求

  • 请求方法为OPTIONS
  • 请求头字段包括 Origin, Access-Control-Request-Method(代表正式的跨域请求可能用到的方法),Access-Control-Request-Headers(代表正式的跨域请求可能用到的头字段)

若预检请求经过验证,则响应字段里会包含以下字段:

Access-Control-Allow-Origin:值为请求头中的origin值或*

Access-Control-Allow-Methods: 代表可被支持的请求方法

Access-Control-Allow-Headers: 代表可被支持的头信息字段

Access-Control-Allow-Credentials: 当请求要求携带证书信息(例如cookie,受权信息等)验证,服务器端是否容许携带

Access-Control-Max-Age: 本次预检请求的有效期,单位为秒

若预检请求没经过验证,则响应字段里不会包含以Access-Control-开头的响应字段,且不会发送正式的跨域请求

正式的跨域请求

与简单请求同样,请求头中附带Origin

携带证书信息的请求

通常状况下,跨域请求不携带证书信息。但若请求的证书模式(credentials mode)被设为include,那么代表该请求须要携带证书信息。请求的证书模式可经过xmlHttpRequest.withCredentials = true设置或调用fetch([url],{mode:"include"})实现。

在简单请求及正式的非简单请求中,请求头附带证书信息,响应头回应:Access-Control-Allow-Credentials:true,并返回请求资源。

在预检请求中,请求头并不会附带证书,响应头会回应:Access-Control-Allow-Credentials:true。

有一点需注意:若服务器端赞成请求携带信息,则Access-Control-Allow-Origin不能为*,只能为请求头中指定的Origin值。

服务器端机制

  1. 检查http头部是否有Origin字段
  2. 没有或不容许,则看成普通请求处理,结束
  3. 如有且容许跨源,再看是不是预检请求(method为OPTIONS)
  4. 是预检请求,返回Access-Control-Allow-Origin,Access-Control-Allow-Methods等信息,内容为空
  5. 不是预检请求,返回Access-Control-Allow-Origin,Access-Control-Allow-Credentials等信息,内容为请求的资源。
相关文章
相关标签/搜索