我在两个不同的域中有两个webapps WebApp1和WebApp2。
我知道这听起来很奇怪,因为Cookie特定于某个域,我们无法从不同的域访问它们;我听说过CROSS-DOMAIN cookie可以在多个webapps之间共享。如何使用CROSS-DOMAIN cookie实现此要求?
注意:我正在尝试使用J2EE webapps
答案 0 :(得分:114)
正如其他人所说,你不能共享cookie,但你可以这样做:
当然,它并不完全安全,你必须在你的应用程序之间创建某种内部协议才能做到这一点。
最后,如果您在每个请求中执行类似的操作,对用户来说会非常烦人,但如果只是第一个请求则不会。
但我认为没有别的办法......
答案 1 :(得分:101)
是的,绝对有可能通过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[name]
其次,在客户端:
在您的ajax请求中,您需要包含2个参数
crossDomain: true
xhrFields: { withCredentials: true }
示例:
type: "get",
url: link,
crossDomain: true,
dataType: 'json',
xhrFields: {
withCredentials: true
}
答案 2 :(得分:59)
据我所知,cookies受到“同源”政策的限制。但是,使用CORS,您可以接收并使用“Server B”cookie从“Server B”上的“Server A”建立持久会话。
虽然,这需要“服务器B”上的一些标题:
Access-Control-Allow-Origin: http://server-a.domain.com
Access-Control-Allow-Credentials: true
您需要在所有“服务器A”请求中发送标记“ withCredentials ”(例如:xhr.withCredentials = true;
)
你可以在这里阅读:
http://www.html5rocks.com/en/tutorials/cors/
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
答案 3 :(得分:21)
没有跨域cookie这样的东西。您可以在foo.example.com
和bar.example.com
之间共享Cookie,但绝不会在example.com
和example2.com
之间共享,这是出于安全原因。
答案 4 :(得分:10)
做谷歌正在做的事情。创建一个PHP文件,在所有3个域上设置cookie。然后在主题要设置的域上,创建一个HTML文件,该文件将加载在其他2个域上设置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>
然后在body标签上添加onload回调。只有当图像完全加载时才会加载文档,即在其他2个域上设置cookie时。 Onload回调:
<head>
<script>
function loadComplete(){
window.location="http://domain1.com";//URL of domain1
}
</script>
</head>
<body onload="loadComplete()">
setcookie.php
我们使用这样的PHP文件在其他域上设置cookie:
<?php
if(isset($_GET['theme'])){
setcookie("theme", $_GET['theme'], time()+3600);
}
?>
现在,Cookie已在三个域上设置。
答案 5 :(得分:8)
您无法跨域共享Cookie。但是,您可以允许所有子域都具有访问权限。要允许example.com
的所有子域都具有访问权限,请将域设置为.example.com
。
虽然不可能otherexample.com
访问example.com
的Cookie。
答案 6 :(得分:7)
您可以尝试使用图片标记将Cookie val推送到另一个域。
尝试执行此操作时,您的里程可能会有所不同,因为某些浏览器要求您在WebApp2域上拥有正确的P3P Policy,否则浏览器将拒绝该Cookie。
如果您查看plus.google.com p3p政策,您会看到他们的政策是:
CP =“这不是P3P政策!有关详细信息,请参阅http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657。”
这是他们用于这些跨域请求的+1按钮的策略。
另一个警告是,如果您使用https,请确保图像标记指向https地址,否则不会设置Cookie。
答案 7 :(得分:5)
对how Facebook does it here on nfriedly.com
有一个不错的概述还有浏览器指纹识别,它与cookie不同,但它的用途相似,因为它可以帮助您识别具有相当程度的确定性的用户。有一篇帖子here on Stack Overflow引用了一种指纹识别方法
答案 8 :(得分:3)
跨站点Cookie 被允许,如果:
让我们澄清一个“域”与一个“站点”;我总能很快想起“ URL的解剖”对我有帮助。在此网址https://example.com:8888/examples/index.html
中,请记住以下主要部分(从this paper中获取):
https://
example.com
8888
“路径”部分为:/examples/index.html
。注意“路径”和“站点”之间的区别。
路径
服务器可以在Path
中设置Set-Cookie
属性,但似乎与安全性无关:
请注意,
path
是为了提高性能,而不是出于安全性。即使路径不匹配,具有相同来源的网页仍可以通过document.cookie访问cookie。
站点
根据web.dev article,SameSite属性可以限制或允许跨站点cookie;但是什么是“站点”?
准确了解“站点”在这里的含义是有帮助的。该站点是域后缀与域后缀的一部分的组合。例如,
www.web.dev
域是web.dev
网站的一部分。
这意味着web.dev
左侧 是一个子域;是的,www
是子域(但subdomain is a part of the host)
在此URL https://www.example.com:8888/examples/index.html
中,请记住以下部分:
https://
example.com
8888
www.example.com
example.com
www
有用的链接:
(注意;我正在Chrome隐身标签中测试我的功能;根据我的chrome://settings/cookies
;我的设置是“阻止隐身第三方Cookie”,因此我无法在隐身模式下测试跨网站Cookie。
答案 9 :(得分: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来源并将Allow Crentials设置为true
<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>
答案 10 :(得分:1)
最聪明的解决方案是遵循Facebook的道路。当你访问任何域名时,facebook如何知道你是谁?它实际上非常simple:
“赞”按钮实际上允许Facebook跟踪外部网站的所有访问者,无论他们是否点击它们。 Facebook可以这样做,因为他们使用 iframe 来显示按钮。 iframe类似于页面中的嵌入式浏览器窗口。使用iframe和按钮的简单图像之间的区别在于 iframe包含完整的网页 - 来自Facebook 。除了按钮和有多少人喜欢当前页面的信息外,此页面上没有太多内容。
因此,当您在cnn.com上看到类似按钮时,您实际上是在同时访问Facebook页面。这允许Facebook在您的计算机上读取cookie,这是您上次登录Facebook时创建的。
每个浏览器中的基本安全规则是,只有创建cookie的网站才能在以后阅读。这就是iframe的优势:它允许Facebook即使在您访问其他网站时也能阅读您的Facebook-cookie。这就是他们如何在cnn.com上认出你并在那里展示你的朋友。
来源:
答案 11 :(得分:1)
我创建了一个NPM模块,该模块允许您跨域共享本地存储的数据: https://www.npmjs.com/package/cookie-toss
通过使用托管在域A上的iframe,您可以将所有用户数据存储在域A上,并通过将请求发布到域A iframe来引用这些数据。
因此,域B,C等可以注入iframe并向其发布请求以存储和访问所需数据。域A成为所有共享数据的中心。
使用域A内的域白名单,可以确保只有从属站点可以访问域A上的数据。
诀窍是将代码放在域A的iframe中,该代码能够识别正在请求的数据。上面的NPM模块中的README对该过程进行了更深入的介绍。
希望这会有所帮助!
答案 12 :(得分:0)
可以使用隐形iframe来获取Cookie。假设有两个域名,a.com和b.com。对于域a.com的index.html,可以添加(通知高度= 0宽度= 0):
<iframe height="0" id="iframe" src="http://b.com" width="0"></iframe>
这样,假设http://b.com设置了Cookie,您的网站就会获得b.com Cookie。
接下来就是通过JavaScript操纵iframe中的网站。如果没有第二个域,iframe中的操作可能会成为一个挑战。但是,如果有权访问这两个域,请参考iframe的src中的正确网页,以便给出想要获得的cookie。
答案 13 :(得分:0)
由于很难制作第三方Cookie,而且某些浏览器也不允许这样做。
您可以尝试将它们存储在HTML5本地存储中,然后将其与前端应用程序的每个请求一起发送。
答案 14 :(得分:0)
除了@Ludovic(approved answer) 答案外,我们还需要在获取 set-cookies 标头时再检查一个选项,
set-cookie: SESSIONID=60B2E91C53B976B444144063; Path=/dev/api/abc; HttpOnly
还要检查 Path 属性值。这应该与您的 API 起始上下文路径相同,如下所示
https://www.example.com/dev/api/abc/v1/users/123
或在不确定上下文路径时使用以下值
Path=/;
答案 15 :(得分:-3)
在Cookie
Web 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;
}
}
}