我在两个不同的域中有两个webapps WebApp1和WebApp2。
- 我正在HttpResponse中的WebApp1中设置cookie。
- 如何从WebApp2中的HttpRequest读取相同的cookie?
我知道这听起来很奇怪,因为Cookie是特定于给定域的,并且我们无法从不同域访问它们。但是,我听说过可以在多个Web应用程序之间共享的跨域Cookie。如何使用跨域Cookie来实现此要求?
注意:我正在使用J2EE webapps尝试此操作
我在两个不同的域中有两个webapps WebApp1和WebApp2。
我知道这听起来很奇怪,因为Cookie是特定于给定域的,并且我们无法从不同域访问它们。但是,我听说过可以在多个Web应用程序之间共享的跨域Cookie。如何使用跨域Cookie来实现此要求?
注意:我正在使用J2EE webapps尝试此操作
Answers:
是的,绝对可以通过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
}
就像其他人说的那样,您无法共享Cookie,但是您可以执行以下操作:
当然,它不是完全安全的,您必须在应用之间创建某种内部协议才能做到这一点。
最后,如果您在每个请求中都执行类似的操作,那么对于用户来说将是非常烦人的,但是如果这只是第一个请求,则不会如此。
但我认为别无他法...
cookiebaker
会更好;-)
据我所知,cookie受“相同来源”政策的限制。但是,通过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/zh-CN/tutorials/cors/
https://developer.mozilla.org/zh-CN/docs/HTTP/Access_control_CORS
没有跨域Cookie。您可以在foo.example.com
和bar.example.com
之间共享一个Cookie ,但不能在example.com
和之间共享一个cookie example2.com
,这是出于安全原因。
foo.example.com
和之间共享Cookie bar.example.com
?
最明智的解决方案是遵循Facebook的做法。当您访问任何域时,facebook如何知道您是谁?实际上非常简单:
“喜欢”按钮实际上允许Facebook跟踪外部网站的所有访问者,无论他们是否单击它。Facebook之所以可以这样做是因为他们使用iframe来显示按钮。iframe类似于页面内的嵌入式浏览器窗口。使用iframe和按钮的简单图片之间的区别在于iframe包含来自Facebook的完整网页。除了按钮和有关有多少人喜欢当前页面的信息之外,此页面上没有什么其他操作。
因此,当您在cnn.com上看到一个点赞按钮时,您实际上是在同时访问一个Facebook页面。这样一来,Facebook便可以读取您计算机上的cookie,该cookie是您上次登录Facebook时创建的。
每个浏览器中的基本安全规则是,只有创建Cookie的网站才能稍后读取它。这就是iframe的优势:即使您访问其他网站,它也可以使Facebook读取您的Facebook cookie。这就是他们在cnn.com上识别您并在其中显示您的朋友的方式。
资源:
做Google在做什么。创建一个在所有3个域上设置cookie的PHP文件。然后在要设置主题的域上,创建一个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时)才加载文档。上载回调:
<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。
您不能跨域共享Cookie。但是,您可以允许所有子域都可以访问。要允许的所有子域example.com
访问,请将域设置为.example.com
。
不过,无法授予otherexample.com
对example.com
的Cookie的访问权限。
.google.com
然后浏览到YouTube时cookie 如何显示?
您可以尝试使用image标签将cookie val推送到另一个域。
尝试执行此操作时,您的里程可能会有所不同,因为某些浏览器要求您在WebApp2域上具有适当的P3P策略,否则浏览器将拒绝cookie。
如果您查看plus.google.com p3p政策,您会发现他们的政策是:
CP =“这不是P3P政策!有关更多信息,请参见http://www.google.com/support/accounts/bin/answer.py?hl=zh_CN&answer=151657。”
这是他们针对这些跨域请求的+1按钮使用的策略。
另一个警告是,如果您使用的是https,请确保图像标记也指向https地址,否则将不会设置cookie。
有一个体面的概述的Facebook怎么会在这里做它nfriedly.com
还有“浏览器指纹”,它与cookie不同,但起着类似的作用,因为它可以帮助您确定一定程度的确定性。在Stack Overflow上有一篇文章引用了一种指纹识别方法
可以使用不可见的iframe来获取Cookie。假设有两个域,即a.com和b.com。对于域名a.com的index.html,可以添加(注意height = 0 width = 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一个人想要的东西。
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>
我创建了一个NPM模块,该模块可让您跨域共享本地存储的数据:https: //www.npmjs.com/package/cookie-toss
通过使用托管在域A上的iframe,您可以将所有用户数据存储在域A上,并通过将请求发布到域A iframe来引用这些数据。
因此,域B,C等可以注入iframe并向其发布请求以存储和访问所需数据。域A成为所有共享数据的中心。
使用域A内的域白名单,可以确保只有从属站点可以访问域A上的数据。
诀窍是将代码放在域A的iframe中,该代码能够识别正在请求的数据。上述NPM模块中的自述文件将更深入地介绍该过程。
希望这可以帮助!
读 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;
}
}
}