HTTP访问控制(CORS)踩坑小记

前几天在帮后端排查一个cors的问题的时候发现的一些小坑特此记录

cors的本质是出于安全原因,浏览器限制从脚本内发起的跨源http请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非使用CORS头文件。

跨域并非一定是浏览器限制了跨站请求,也有可能是跨站请求可以正常发起,但是返回结果被浏览器拦截了。最好的例子是 CSRF 跨站攻击原理,请求是发送到了后端服务器无论是否跨域!注意:有些浏览器不允许从 HTTPS 的域跨域访问 HTTP,比如 chrome 和 Firefox,这些浏览器在请求还未发出的时候就会拦截请求。

本case场景描述如下: 用户在a.com域名下跨域访问b.com域名下的api接口,使用了XMLHttpRequest的跨域头请求。域名b.com也允许了可以跨域 Access-Control-Allow-Origin 但是很奇怪在访问b.com的接口时有些api能访问成功,有些api访问失败。排查发现访问失败的api都是需要用户的登录态的。但是用户已经在b.com登录过了。把XMLHttpRequest请求换成jsonp请求则都可以请求成功(这好像是废话)。。。由此推测XMLHttpRequest 添加cors头的时候没有把b.com的 用户cookie信息带过去。

翻看MDN文档https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS 找到答案如下:


xhr.withCredentials

Fetch 与 CORS 的一个的特性是,可以基于 HTTP cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨域 XMLHttpRequest 或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。** 


var xhr = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';
    
function callOtherDomain(){
  if(xhr) {
    xhr.open('GET', url, true);
    xhr.withCredentials = true;//这个是重点
    xhr.onreadystatechange = handler;
    xhr.send(); 
  }
}

将 XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies。服务器端的响应需要携带 Access-Control-Allow-Credentials: true ,浏览器才会把响应内容返回给请求的发送者。

HTTP访问控制(CORS)踩坑小记 第1张

另外需要注意的是

对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。 这是因为请求的首部中携带了 Cookie 信息,如果 Access-Control-Allow-Origin 的值为“*”,请求将会失败。而将 Access-Control-Allow-Origin 的值设置为 http://foo.example,则请求将成功执行。

tips:

在跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头Access-Control-Expose-Headers 头让服务器把允许浏览器访问的头放入白名单,例如:

Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

这样浏览器就能够通过getResponseHeader访问X-My-Custom-Header和 X-Another-Custom-Header 响应头了。


本文标题:HTTP访问控制(CORS)踩坑小记
本文链接:https://56way.com/p/111.html
作者授权:除特别说明外,本文由 无路 原创编译并授权 小无路 刊载发布。
版权声明:本文使用「署名-非商业性使用-相同方式共享 4.0 国际」创作共享协议,转载或使用请遵守署名协议。

已有2位网友发表了看法:

1L小无路 2018-04-13 11:17:01 回复
http://plantuml.com/ 代码生成时序图
2L小无路 2018-11-13 18:24:01 回复
https://github.com/video-dev/hls.js/issues/1998

发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。