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

时间:2013-03-01 09:53:09

标签: internet-explorer cookies cross-domain

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

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

www.website_domain.com

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

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

  1. 对来自的回复使用http://www.api_domain.com 即使有跨域请求也可以发送cookie。
  2. 使用来源在Access-Control-Allow-Credentials: true的页面上创建iframe http://www.website_domain.com,让两个窗口进行通信 彼此使用HTML5 post messages并委托所有人 向http://www.api_domain.com提出请求的责任 iframe。
  3. 如果可能的话,我更倾向于使用选项1,因为它允许您编写Javascript代码以使用http://www.api_domain.com上的API,就像您将其编写为触摸同域API一样。要使用iframe方法,我们需要学习或创建一些框架,用于向iframe发送类似AJAX的请求,以及成功和错误处理程序。这也意味着我们需要创建要加载到iframe中的代码,iframe只是用于访问API URL的一大堆精简包装器。与第一种方法相比,它看起来更丑陋,更难理解,更难理解。

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

    我是否可以使用一些黑客或魔法咒语来使Internet Explorer尊重www.api_domain.com标题,或IE可识别的其他标题?

2 个答案:

答案 0 :(得分: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。它不漂亮,但它的工作原理。文章中也提到了这种方法。你会想要小心,因为它开启了会话劫持的可能性。

答案 1 :(得分:0)

IE8 +可替代XMLHttpRequest,支持XDomainRequest凭据。无论如何,XDomainRequest不是由JQuery实现的,因为它的功能少于XMLHttpRequest提供的功能,但有像jQuery CORS Plugin这样的插件可以提供你需要的东西。

  

jQuery插件,它透明地添加了跨源资源共享   (CORS)浏览器(包括IE8 +)允许跨域Ajax   请求使用Cookie和标头支持。

我认为但不确定IE在Access-Control-Allow-Origin: *这样的标题中不支持通配符。