2010-07-27 125 views
153

我有两个web应用WebApp1和webapp2的在两个不同的领域。跨域饼干

  1. 我在HttpResponse的WebApp1中设置了一个cookie。
  2. 如何从WebApp2中的HttpRequest中读取同一个cookie?

我知道这听起来很奇怪,因为cookie是特定于给定域的,我们不能从不同的域访问它们;然而,我听说过可以跨多个webapps共享的跨域cookies。如何使用CROSS-DOMAIN cookies来实现这个要求?

注:我与J2EE尝试此的webapps

回答

13

有交叉域的Cookie没有这样的事情。你可以共用一个Cookie foo.example.combar.example.com但绝不之间example.comexample2.com之间,这就是出于安全原因。

+0

嗨感谢您的回复,ü可以请加配置部分更清晰,如何在j2ee环境中创建/配置域和子域NT ??? – SundarJavaDeveloper 2010-07-27 11:29:15

+1

这是一个更适合http://serverfault.com的问题,您将从该领域的专家那里获得答案。 – 2010-07-27 11:36:24

+0

嗨, 我试着有两个webapps WebApp.domain.com ==>这里我添加cookie的respose如下: Cookie cookie = new Cookie(“namedCookie”,“test”); cookie.setDomain(“。domain.com”); response.addCookie(cookie); WebApp1.domain.com ==>在这里,我试图访问cookie如下,但无法访问 Cookie [] cks = request.getCookies(); (int i = 0; i SundarJavaDeveloper 2010-07-28 07:01:08

8

你不能跨域共享饼干。但是,您可以允许所有子域名拥有访问权限。要允许所有子域example.com有权访问,请将域设置为.example.com

它不可能给otherexample.com访问example.com的饼干虽然。

+22

怎么会'.google .com浏览YouTube时出现cookies? – Hawken 2012-10-26 21:06:20

+19

谷歌分析标签。这些cookie来自google.com,而不是来自youtube.com。 – Entendu 2013-09-12 22:58:40

88

至于别人说,你不能分享饼干,但你可以做这样的事情:

  1. 集中到单个域中所有的cookies,让我们说cookiemaker.com
  2. 当用户发出请求到example.com,您重定向他cookiemaker.com
  3. cookiemaker.com重定向他回example.com与您需要的信息

当然,这不是一个完全安全的,你必须在你的应用程序之间创建一些内部协议才能做到这一点。

最后,如果你做的每一个要求类似的东西,这将是对用户来说非常讨厌,但如果它不只是第一个。

但我认为没有其他办法...

+30

如果没有其他方法,那么StackExchange/OpenID是如何工作的? – Hawken 2012-10-26 21:30:05

+42

@Hawken StackExchange/OpenID遵循上述相同的过程。您被引导至不同的网站(SO> SX),确认您的身份,然后将其引导回您的所需信息。 [OpenID规范](http://openid.net/developers/specs/)解释更多,虽然[维基百科更清楚地说明](http://en.wikipedia.org/wiki/OpenID#Logging_in)。 – 2013-09-30 22:42:29

+0

@alcuadrado如何通过此解决方案识别不同的用户?假设来自a.com的用户登录并设置了所需的信息。现在,当用户转到使用相同脚本/应用程序/插件的b.com时,您将如何知道这是同一用户? – 2015-07-03 08:24:31

50

据我所知道的一个方法引用,饼干由“同根同源”的政策限制。但是,使用CORS,您可以接收并使用“服务器B”Cookie从“服务器B”上的“服务器A”建立持久会话。

虽然,这需要在 “服务器B” 的一些标题:

Access-Control-Allow-Origin: http://server-a.domain.com 
Access-Control-Allow-Credentials: true 

而且你将需要发送的标志 “withCredentials” 上的所有 “服务器A” 的要求(例如:xhr.withCredentials = true;

你可以阅读一下:

http://www.html5rocks.com/en/tutorials/cors/

https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

+6

这不适用于某些用户,因为如果禁用了第三方Cookie,CORS Cookie将不起作用。 [默认为Safari](http://blog.prowebsoftware.net/2013/08/safari-cors-requests-withcredentials/)例如[Mozilla设置](http://www.goeszen.com/how-to-get-cookies-working-with-cors-jquery-and-xhr-ajax.html)。 Google [更多示例](https://www.google.com/#q=withCredentials+third-party-cookies)和[关于为什么Facebook的文章](http://www.nfriedly.com/techblog/2010/ 08/how-facebook-sets-and-uses-cross-domain-cookies /)不使用第三方cookie。 – robocat 2016-02-24 03:36:20

+0

堆栈交换/ openID使用CORS吗? – RayLoveless 2016-06-24 20:01:33

+0

FWIW我刚刚测试了一个正常的CORS withCredentials XHR,它在FF/Safari/Chrome上工作...虽然我不怀疑Facebook /谷歌使用更复杂的方案 – rogerdpack 2017-04-14 19:11:19

-1

可以使用隐形iframe来获取cookie。假设有两个域名,a.com和b.com。对于域a.com的index.html的一个可以添加(注意高度= 0 WIDTH = 0):

<iframe height="0" id="iframe" src="http://b.com" width="0"></iframe> 

这样,你的网站将获得b.com饼干假设http://b.com设置的cookie。

接下来的事情就是通过JavaScript操作iframe中的网站。如果不拥有第二个域,那么iframe内的操作可能会成为一个挑战。但是如果能够访问这两个域,那么在iframe的src处引用正确的网页应该给人想要的cookie。

+3

只是一个警告:在iframe中存在一些严重的问题在Safari上。他们显然不工作跨域。 – mvds 2013-12-04 11:23:08

7

您可以尝试使用图像标记将cookie val推送到另一个域。试图做到这一点,因为一些浏览器需要你对webapp2的域或浏览器将拒绝该cookie适当P3P Policy

您的里程可能会有所不同。

如果你看一下plus.google.com P3P策略,你会看到,他们的政策是:“这不是一个P3P政策的更多信息,请参见http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657。”

CP =

这是他们为这些跨域请求使用+1按钮的策略。

另一个警告是,如果你在https上,请确保图像标签指向一个https地址,否则cookie将不会被设置。

+0

小心细化一下? – frequent 2014-11-25 08:21:52

70

是的,绝对有可能通过domain2.com从domain1.com获取cookie,我完全与社交网络的社交插件存在同样的问题,经过一天的研究,我找到了解决方案。

首先你需要有这些头文件在服务器端:

header("Access-Control-Allow-Origin: http://origin.domain:port"); 
header("Access-Control-Allow-Credentials: true"); 
header("Access-Control-Allow-Methods: GET, POST"); 
header("Access-Control-Allow-Headers: Content-Type, *"); 

使用PHP文件,你可以使用$ _COOKIE [名]。

在客户端:

有了您的Ajax请求需要包含2个参数

crossDomain: true 
xhrFields: { withCredentials: true } 

例子:

type: "get", 
url: link, 
crossDomain: true, 
dataType: 'json', 
xhrFields: { 
    withCredentials: true 
} 
+5

或者如果您不想过滤原点,只需使用$ _SERVER ['HTTP_ORIGIN']而不是* – 2015-04-29 16:22:20

+1

这是唯一对我有效的事情。另外,*未被接受为原点,因此需要@Joel Teply的提示。 – Guessed 2015-09-27 20:14:41

+1

当我在localhost上运行代码时它工作得很好,但是在运行时我没有看到cookie被设置为API,并且我得到了预期的401(未授权)错误。有任何想法吗? – 2015-10-14 13:17:41

9

做什么谷歌正在做什么。创建一个PHP文件,在所有3个域上设置cookie。然后在要设置主题的域上创建一个HTML文件,该文件将加载在另外两个域上设置cookie的PHP文件。例如:

<html> 
    <head></head> 
    <body> 
     <p>Please wait.....</p> 
     <img src="http://domain2.com/setcookie.php?theme=whateveryourthemehere" /> 
     <img src="http://domain3.com/setcookie.php?theme=whateveryourthemehere" /> 
    </body> 
</html> 

然后在身体标记添加一个onload回调。该文档只会在图像完全加载时加载,即在另外两个域上设置cookie时加载。的onload回调:

<head> 
    <script> 
    function loadComplete(){ 
     window.location="http://domain1.com";//URL of domain1 
    } 
    </script> 
</head> 
<body onload="loadComplete()"> 

setcookie.php 

我们设置Cookie的使用PHP文件中像这样的其他领域:

<?php 
if(isset($_GET['theme'])){ 
    setcookie("theme", $_GET['theme'], time()+3600); 
} 
?> 

现在Cookie是在三个领域设置。

+3

好,那我们怎样才能从另一个领域读取? – Elby 2015-08-18 09:12:15

+0

如果启用了“阻止第三方Cookie”功能,则此功能无效。 – Jens 2016-07-25 18:18:26

-1

CookieWeb Api

var cookie = actionContext.Request.Headers.GetCookies("newhbsslv1"); 


        Logger.Log("Cookie " + cookie, LoggerLevel.Info); 
        Logger.Log("Cookie count " + cookie.Count, LoggerLevel.Info); 

        if (cookie != null && cookie.Count > 0) 
        { 
         Logger.Log("Befor For " , LoggerLevel.Info); 
         foreach (var perCookie in cookie[0].Cookies) 
         { 
          Logger.Log("perCookie " + perCookie, LoggerLevel.Info); 

          if (perCookie.Name == "newhbsslv1") 
          { 
           strToken = perCookie.Value; 
          } 
         } 
        } 
1
function GetOrder(status, filter) { 
    var isValid = true; //isValidGuid(customerId); 
    if (isValid) { 
     var refundhtmlstr = ''; 
     //varsURL = ApiPath + '/api/Orders/Customer/' + customerId + '?status=' + status + '&filter=' + filter; 
     varsURL = ApiPath + '/api/Orders/Customer?status=' + status + '&filter=' + filter; 
     $.ajax({ 
      type: "GET", 
      //url: ApiPath + '/api/Orders/Customer/' + customerId + '?status=' + status + '&filter=' + filter, 
      url: ApiPath + '/api/Orders/Customer?status=' + status + '&filter=' + filter, 
      dataType: "json", 
      crossDomain: true, 
      xhrFields: { 
       withCredentials: true 
      }, 
      success: function (data) { 
       var htmlStr = ''; 
       if (data == null || data.Count === 0) { 
        htmlStr = '<div class="card"><div class="card-header">Bu kriterlere uygun sipariş bulunamadı.</div></div>'; 
       } 
       else { 
        $('#ReturnPolicyBtnUrl').attr('href', data.ReturnPolicyBtnUrl); 
        var groupedData = data.OrderDto.sort(function (x, y) { 
         return new Date(y.OrderDate) - new Date(x.OrderDate); 
        }); 
        groupedData = _.groupBy(data.OrderDto, function (d) { return toMonthStr(d.OrderDate) }); 
        localStorage['orderData'] = JSON.stringify(data.OrderDto); 

        $.each(groupedData, function (key, val) { 

         var sortedData = groupedData[key].sort(function (x, y) { 
          return new Date(y.OrderDate) - new Date(x.OrderDate); 
         }); 
         htmlStr += '<div class="card-header">' + key + '</div>'; 
         $.each(sortedData, function (keyitem, valitem) { 
          //Date Convertions 
          if (valitem.StatusDesc != null) { 
           valitem.StatusDesc = valitem.StatusDesc; 
          } 

          var date = valitem.OrderDate; 
          date = date.substring(0, 10).split('-'); 
          date = date[2] + '.' + date[1] + '.' + date[0]; 
          htmlStr += '<div class="col-lg-12 col-md-12 col-xs-12 col-sm-12 card-item clearfix ">' + 
         //'<div class="card-item-head"><span class="order-head">Sipariş No: <a href="ViewOrderDetails.html?CustomerId=' + customerId + '&OrderNo=' + valitem.OrderNumber + '" >' + valitem.OrderNumber + '</a></span><span class="order-date">' + date + '</span></div>' + 
         '<div class="card-item-head"><span class="order-head">Sipariş No: <a href="ViewOrderDetails.html?OrderNo=' + valitem.OrderNumber + '" >' + valitem.OrderNumber + '</a></span><span class="order-date">' + date + '</span></div>' + 
         '<div class="card-item-head-desc">' + valitem.StatusDesc + '</div>' + 
         '<div class="card-item-body">' + 
          '<div class="slider responsive">'; 
          var i = 0; 
          $.each(valitem.ItemList, function (keylineitem, vallineitem) { 
           var imageUrl = vallineitem.ProductImageUrl.replace('{size}', 200); 
           htmlStr += '<div><img src="' + imageUrl + '" alt="' + vallineitem.ProductName + '"><span class="img-desc">' + ProductNameStr(vallineitem.ProductName) + '</span></div>'; 
           i++; 
          }); 
          htmlStr += '</div>' + 
         '</div>' + 
        '</div>'; 
         }); 
        }); 

        $.each(data.OrderDto, function (key, value) { 
         if (value.IsSAPMigrationflag === true) { 
          refundhtmlstr = '<div class="notify-reason"><span class="note"><B>Notification : </B> Geçmiş siparişleriniz yükleniyor. Lütfen kısa bir süre sonra tekrar kontrol ediniz. Teşekkürler. </span></div>'; 
         } 
        }); 
       } 
       $('#orders').html(htmlStr); 
       $("#notification").html(refundhtmlstr); 
       ApplySlide(); 
      }, 
      error: function() { 
       console.log("System Failure"); 
      } 
     }); 
    } 
} 

的Web.config

包括UI的起源和设置允许Crentials真

<httpProtocol> 
     <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="http://burada.com" /> 
     <add name="Access-Control-Allow-Headers" value="Content-Type" /> 
     <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /> 
     <add name="Access-Control-Allow-Credentials" value="true" /> 
     </customHeaders> 
    </httpProtocol>