CROS
通常在浏览器中会遇到如下的报错。
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://example.com/api/login.
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
这源于浏览器中的同源策略,主要是为了防止出现跨站请求伪造攻击。
通常,会通过 cookie 保存认证和维持 Session 信息,例如当登录 facebook.com 之后会保存相应的 cookie 信息,这样后续就无需重新登录。
当打开了 evil.com 异常网站之后,如果在该网站中访问了 facebook.com 的接口,同时又因为之前登录的 cookie 信息,那么就可以伪造发送相关请求。
但是,可能同时会拦截掉一些正常请求,如下分成两种类型进行处理。
简单请求
发送的请求头中同时会包含 Origin 字段,例如如下的示例。
GET /api/login HTTP/1.1
Origin: http://api.foobar.com
通过 Origin 标识请求来源,包括了协议、域名、端口,服务器根据改信息决定是否同意这次请求。
如果 Origin 指定的源在服务器允许范围内,那么服务器会返回包含 Access-Control 相关的头,如果不包含那么就会抛出异常,相关的头包含如下几个:
Access-Control-Allow-Origin必须,要么是请求时的Origin字段值,要么是*表示允许任意域名请求。Access-Control-Allow-Credentials可选,是否允许发送 Cookie,只能设置为true,如果不允许那么直接删除即可。Access-Control-Expose-Headers可选,那些响应头可以暴露给浏览器中运行的脚本,以响应跨源请求。
非简单请求
常见的是 PUT DELETE 或者 Content-Type 字段为 application/json 类型,此种类型会正式发送请求前增加一次预检请求,也就是 OPTIONS 类型,关键字段同样为 Origin 头,同时还包含如下几个字段:
Access-Control-Request-Method必须,用来列出浏览器请求会用到的方法。Access-Control-Request-Headers可选,通过逗号分割,标识 CORS 请求会额外发送的头信息字段。
服务器返回头,除了上述 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials 之外,还支持如下:
Access-Control-Allow-Methods允许的操作方法,例如GET, POST, PUT。Access-Control-Allow-Headers允许的头信息。Access-Control-Max-Age可选,用来指定本次预检请求的有效期,单位为秒。