IE 8和9中没有iframe的跨域cookie?

Mar*_*ery 5 cookies internet-explorer cross-domain

假设我控制两个域,www.api_domain.com并且www.website_domain.com.www.api_domain.com提供一个API,要求用户进行身份验证,然后使用会话cookie来识别发出请求的用户.www.website_domain.com将脚本加载到其页面上www.api_domain.com,该脚本希望www.api_domain.com使用当前用户的cookie 调用API URL,并以某种方式在页面上使用结果www.website_domain.com.

对于最初加载脚本或任何不需要用户会话cookie工作的API URL,最简单的解决方案就是使用

Access-Control-Allow-Origin: http://www.website_domain.com
Run Code Online (Sandbox Code Playgroud)

来自的回复标题www.api_domain.com.这似乎在除了IE之外的所有浏览器上开箱即用,虽然IE不会尊重使用jQuery的AJAX方法制作的AJAX请求的Allow-Origin标头,但是像xdr.js这样的库在幕后做了一些魔术.使jQuery,IE和Allow-Origin标头一起玩得很好,并且在所有其他浏览器中表现得像(我不知道xdr.js的详细信息,但就我所见,它对于非凭证的请求非常有效) ).

当我想点击一个http://www.api_domain.com需要用户会话cookie 的URL时,就会出现问题.在浏览器无关的设置中讨论此问题时,通常会提出两种解决方案:

  1. Access-Control-Allow-Credentials: true即使使用跨域请求,也可以使用响应来发送cookie.
  2. http://www.website_domain.com带有origin 的页面上创建一个iframe http://www.api_domain.com,让两个窗口使用HTML5 post消息相互通信,并委托http://www.api_domain.com向iframe 发出请求的所有责任.

如果可能的话,我更倾向于使用选项1,因为它允许您编写Javascript代码以使用API​​,http://www.api_domain.com就像您编写它以触摸相同域API一样.要使用iframe方法,我们需要学习或创建一些框架,用于向iframe发送类似AJAX的请求,以及成功和错误处理程序.这也意味着我们需要创建要加载到iframe中的代码,iframe只是用于访问API URL的一大堆精简包装器.与第一种方法相比,它看起来更丑陋,更难以理解.

但是,我无法弄清楚如何让选项1在IE上运行.我正在设置Access-Control-Allow-Credentials: true我的API网址,而所有其他浏览器都会向这些网址发送Cookie,但即使使用xdr.js库,IE 9也不会.(我没有在IE 8上测试过.)没有任何其他症状需要报告.当我在IE的开发人员工具中查看它们时,我可以看到响应中的正确Access-Control-Allow-OriginAccess-Control-Allow-Credentials标题www.api_domain.com,但请求中没有cookie标头.

是否有一些黑客或魔法咒语,我可以使用它来使Internet Explorer尊重Access-Control-Allow-Credentials标题,或IE可以识别的其他一些标题?

小智 9

IE9或更低版本中无法使用选项1,因为使用XMLHttpRequest不支持CORS.此外,如果您尝试使用XDomainRequest,您将永远无法发送任何cookie以及您的请求.我一直在这条路上工作,编写一个ui测试库,用于testwarm.你想做的就是不可能以这种方式.

以下是前微软开发人员Eric Law的一篇文章,详细讨论了该问题:http: //blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and- workarounds.aspx

相关部分明确表示,在IE 8和9中无法发送带有CORS请求的cookie,如下所示:

在Internet Explorer 8中,引入了XDomainRequest对象.此对象允许AJAX应用程序直接通过确保HTTP响应只能由当前页面读取(如果数据源指示响应是公共的)来直接发出安全的跨源请求.这样,同源策略安全保证受到保护.响应表明他们愿意通过将Access-Control-Allow-Origin HTTP响应头包含值*或调用页的确切来源来允许跨域访问.

在设计新对象时,确保现有站点和服务不会受到威胁是我们的首要任务.为此,我们对可以使用XDomainRequest对象进行何种请求施加了一些限制.

...

5:请求不会发送身份验证或cookie

为了防止滥用用户的环境权限(例如cookie,HTTP凭证,客户端证书等),请求将被剥离cookie和凭据,并将忽略HTTP响应中的任何身份验证质询或Set-Cookie指令.XDomainRequests不会在以前经过身份验证的连接上发送,因为某些Windows身份验证协议(例如NTLM/Kerberos)是基于每个连接而不是基于请求的.

希望对跨源请求执行用户身份验证的站点可以使用显式方法(例如POST正文或URL中的令牌)来传递此身份验证信息,而不会冒用户的环境权限.

现在假设你控制了两个位置,你可能会创建一个服务器到服务器的身份验证过程,然后通过你的请求传递从域提供的其他域的会话ID.它不漂亮,但它的工作原理.文章中也提到了这种方法.你会想要小心,因为它开启了会话劫持的可能性.