没有iframe的IE 8和9中的跨域Cookie? [英] Cross-domain cookies in IE 8 and 9 without an iframe?

查看:48
本文介绍了没有iframe的IE 8和9中的跨域Cookie?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我控制两个域, www.api_domain.com www.website_domain.com www.api_domain.com 提供了一个API,该API要求用户进行身份验证,然后使用会话cookie识别正在发出请求的用户。 www.website_domain.com 将脚本从 www.api_domain.com 加载到其页面上,该脚本希望进行呼叫使用当前用户的Cookie来访问 www.api_domain.com 上的API URL,并在 www.website_domain.com



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

 访问控制允许来源:http://www.website_domain.com 

标头来自 www.api_domain.com 的响应。在IE之外的所有浏览器中,这似乎都是开箱即用的,尽管IE不会尊重使用jQuery的AJAX方法发出的AJAX请求的Allow-Origin标头,但还是有xdr.js之类的库在幕后发挥了神奇作用使jQuery,IE和Allow-Origin标头可以很好地协同工作,并且在所有其他浏览器中的行为都一样(我不知道xdr.js的作用的详细信息,但据我所知,它非常适用于非凭据请求)。



问题是当我想点击 http://www.api_domain.com 上的URL时出现的需要用户的会话Cookie。当在与浏览器无关的环境中讨论此问题时,通常提出两种解决方案:


  1. 使用访问控制-Allow-Credentials:对于来自
    的响应,则为true
    ,即使使用跨域请求也可以发送Cookie。

  2. http://www.website_domain.com 的页面上创建一个iframe,其起始位置为
    http://www.api_domain.com ,让两个窗口使用 HTML5帖子,并将所有
    的责任委托给 http://www.api_domain.com
    iframe。

如果可能的话,我非常希望使用选项1,因为它使您可以编写Javascript代码以使用 http://www.api_domain.com 上的API,就像编写触摸同一域API一样。要使用iframe方法,我们需要学习或创建一些框架,以通过成功和错误处理程序将类似AJAX的请求发送到iframe。这也意味着我们需要创建要加载到iframe中的代码,这只是用于访问API URL的一堆瘦包装。似乎比第一种方法更丑陋,更棘手并且更难理解。



但是,我不知道如何在IE上使用选项1。我在我的API URL上设置了 Access-Control-Allow-Credentials:true ,所有其他浏览器都向这些URL发送了cookie,但是IE 9却没有, xdr.js库。 (我尚未在IE 8上进行过测试。)没有其他可报告的症状。我可以在响应中看到正确的 Access-Control-Allow-Origin Access-Control-Allow-Credentials 标头从 www.api_domain.com 中获取,当我在IE的开发人员工具中查看它们时,但请求中没有cookie标头。



我是否可以使用一些技巧或魔术来使Internet Explorer尊重 Access-Control-Allow-Credentials 标头,或者可以使用其他标头IE可以识别吗?

解决方案

在IE9或更低版本中无法使用选项1,因为不支持使用XMLHttpRequest的CORS。此外,如果您尝试使用XDomainRequest,则将永远无法将任何Cookie与您的请求一起发送。我在这条路上走了好几次,写一个用于testwarm的ui测试库。


这里是前微软开发人员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,HTTP凭据,客户端证书等),将不发送任何身份验证或cookie。


Cookie和凭据,并且将忽略HTTP响应中的任何身份验证挑战或Set-Cookie指令。 XDomainRequest不会在以前已验证的连接上发送,因为某些Windows验证协议(例如NTLM / Kerberos)是基于每个连接的,而不是基于每个请求的。


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


现在假设您同时控制两个位置,则可以创建一个服务器到服务器的身份验证过程,然后继续传递从该域提供的会话ID(对于另一个域,该域实际上是客户端通过的)你的申请。它不漂亮,但是可以用。本文中也提到了这种方法。不过,您将要小心,因为它打开了会话劫持的可能性。


Suppose I control two domains, www.api_domain.com and www.website_domain.com. www.api_domain.com offers an API that requires the user to authenticate and then uses a session cookie to recognise the user who is making requests. www.website_domain.com loads a script onto its pages from www.api_domain.com and that script wants to make calls to API URLs on www.api_domain.com with the current user's cookie and use the results in some way on the page from www.website_domain.com.

For initially loading the script, or for any API URLs that don't require the user's session cookie to work, the easiest solution is simply to use an

Access-Control-Allow-Origin: http://www.website_domain.com

header on the response from www.api_domain.com. This seems to work out of the box on all browsers besides IE, and although IE won't respect the Allow-Origin header on AJAX requests made using jQuery's AJAX methods, there are libraries like xdr.js which do some magic behind the scenes to make jQuery, IE and the Allow-Origin header play nice together and behave like in all other browsers (I don't know the details of what xdr.js does, but it works perfectly for non-credentialed requests as far as I can see).

The problem comes when I want to hit a URL on http://www.api_domain.com that requires the user's session cookie. When this problem is discussed in a browser-agnostic setting, two solutions are usually proposed:

  1. Use Access-Control-Allow-Credentials: true on the response from to make cookies be sent even with cross-domain requests.
  2. Create an iframe on the page on http://www.website_domain.com with origin http://www.api_domain.com, have the two windows communicate with each other using HTML5 post messages and delegate all responsibility for making requests to http://www.api_domain.com to the iframe.

I would greatly prefer to use option 1 if possible, since it lets you write your Javascript code to use the API on http://www.api_domain.com in the same way that you would write it to touch a same-domain API. To use the iframe approach, we'd need to learn or create some framework for sending AJAX-like requests to the iframe, with success and error handlers. It also means we need to create the code to be loaded into the iframe, which will just be a whole chunk of thin wrappers for hitting the API URLs. It just seems uglier, trickier, and harder to understand than the first approach.

However, I can't figure out how to make option 1 work on IE. I'm setting Access-Control-Allow-Credentials: true on my API URLs, and all other browsers send cookies to those URLs, but IE 9 doesn't, even with the xdr.js library. (I haven't tested on IE 8.) There are no other symptoms to report whatsoever. I can see the proper Access-Control-Allow-Origin and Access-Control-Allow-Credentials headers in the responses from www.api_domain.com when I view them in IE's developer tools, but there are no cookie headers in the request.

Is there some hack or magical incantation that I can use to make Internet Explorer respect the Access-Control-Allow-Credentials header, or some other header I can use that IE recognises?

解决方案

Option 1 is not possible in IE9 or below because there is no support for CORS using the XMLHttpRequest. Additionally, if you try to use XDomainRequest, you will never be able to send any cookies along with your request. I've been down this road several times working on writing a ui testing library to be used with testswarm. What you want to do is just not possible in that manner.

Here is a post by Eric Law, an ex-Microsoft developer, discussing the issue in detail: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

The relevant sections, which make clear that sending cookies with a CORS request is impossible in IE 8 and 9, are as follows:

In Internet Explorer 8, the XDomainRequest object was introduced. This object allows AJAX applications to make safe cross-origin requests directly by ensuring that HTTP Responses can only be read by the current page if the data source indicates that the response is public; in that way, the Same Origin Policy security guarantee is protected. Responses indicate their willingness to allow cross domain access by including the Access-Control-Allow-Origin HTTP response header with value *, or the exact origin of the calling page.

When designing the new object, ensuring that existing sites and services would not be put at risk was our top priority. To that end, we imposed a number of restrictions on what sort of requests can be made with the XDomainRequest object.

...

5: No authentication or cookies will be sent with the request

In order to prevent misuse of the user’s ambient authority (e.g. cookies, HTTP credentials, client certificates, etc), the request will be stripped of cookies and credentials and will ignore any authentication challenges or Set-Cookie directives in the HTTP response. XDomainRequests will not be sent on previously-authenticated connections, because some Windows authentication protocols (e.g. NTLM/Kerberos) are per-connection-based rather than per-request-based.

Sites that wish to perform authentication of the user for cross-origin requests can use explicit methods (e.g. tokens in the POST body or URL) to pass this authentication information without risking the user’s ambient authority.

Now assuming you control both locations, you could presumably create a server to server authentication process and go about passing a session id of sorts provided from the domain, for the other domain, of which the client is actually on through your request. It's not pretty, but it works. This method is also mentioned in the article. You will want to be careful though because it opens up the possibility for session hijacking.

这篇关于没有iframe的IE 8和9中的跨域Cookie?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆