跨域Cookie

Sun*_*per 217 cookies web-applications cross-domain

我在两个不同的域中有两个webapps WebApp1和WebApp2.

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

我知道这听起来很奇怪,因为cookie特定于某个域,我们无法从不同的域访问它们; 我听说过CROSS-DOMAIN cookie可以在多个webapps之间共享.如何使用CROSS-DOMAIN cookie实现此要求?

注意:我正在尝试使用J2EE webapps

alc*_*ado 122

正如其他人所说,你不能共享cookie,但你可以这样做:

  1. 将所有cookie集中在一个域中,让我们说cookiemaker.com
  2. 当用户向example.com发出请求时,您将其重定向到cookiemaker.com
  3. cookiemaker.com使用您需要的信息将他重定向回example.com

当然,它不是完全安全的,你必须在你的应用程序之间创建某种内部协议来做到这一点.

最后,如果您在每个请求中执行类似的操作,对用户来说会非常烦人,但如果只是第一个请求则不会.

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

  • @Hawken StackExchange/OpenID遵循与上述相同的过程.您将被定向到另一个站点(SO> SX),确认您的身份,然后使用您需要的信息返回SO.[OpenID规范](http://openid.net/developers/specs/)解释了更多,尽管[维基百科做得更明白](http://en.wikipedia.org/wiki/OpenID#Logging_in). (53认同)
  • 如果没有其他方法,那么StackExchange/OpenID如何工作? (39认同)
  • 所有用户实际上都登录 cookiemaker.com。并且它使用特殊且安全的消息将用户重定向到不同的站点,以验证他们是否已登录以及他们是谁。如何实施取决于您,有无数种方法。也许你可以使用这个:http://jwt.io/ (2认同)
  • @ Andrew_1510`cookiebaker`会更好;-) (2认同)

小智 112

是的,绝对有可能通过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, *");
Run Code Online (Sandbox Code Playgroud)

在PHP文件中,您可以使用 $_COOKIE[name]

第二,在客户端:

在您的ajax请求中,您需要包含2个参数

crossDomain: true
xhrFields: { withCredentials: true }
Run Code Online (Sandbox Code Playgroud)

例:

type: "get",
url: link,
crossDomain: true,
dataType: 'json',
xhrFields: {
  withCredentials: true
}
Run Code Online (Sandbox Code Playgroud)

  • 或者,如果您不想过滤原点,只需使用$ _SERVER ['HTTP_ORIGIN']而不是* (5认同)
  • 如果禁用第三方cookie(某些浏览器情况下是自动的),这将不起作用.请参阅https://blog.zok.pw/web/2015/10/21/3rd-party-cookies-in-practice/和http://www.allannienhuis.com/archives/2013/11/03/blocked-第三方会话cookie-in-iframes /更多信息. (4认同)
  • 有人请接受这是一个有效的答案!它回答了问题,但并不完整。还需要提到的是,cookie 必须具有 `SameSite:none; secure` 就像这个答案中所述:/sf/answers/4460987261/ (3认同)
  • 不要使用Joel的技巧,因为它本质上与将其设置为“ *”相同,因为它可能会打开细微的安全漏洞,因此不鼓励使用,请参阅http://stackoverflow.com/questions/12001269/what-are设置访问控制允许起源的安全风险 (2认同)
  • 在哪个域的服务器端? (2认同)

小智 65

据我所知,cookies受到"同源"政策的限制.但是,使用CORS,您可以接收并使用"服务器B"cookie从"服务器B"上的"服务器A"建立持久会话.

虽然,这需要"服务器B"上的一些标题:

Access-Control-Allow-Origin: http://server-a.domain.com
Access-Control-Allow-Credentials: true
Run Code Online (Sandbox Code Playgroud)

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

你可以在这里读到它:

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

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

  • 这对某些用户不起作用,因为如果禁用第三方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. (9认同)

Mor*_*Nia 44

最聪明的解决方案是在这方面遵循 facebook 的路径。当您访问任何域时,facebook 如何知道您是谁?其实很简单

Like 按钮实际上允许 Facebook 跟踪外部站点的所有访问者,无论他们是否点击它。Facebook 可以这样做,因为他们使用iframe来显示按钮。iframe 类似于页面中的嵌入式浏览器窗口。使用 iframe 和按钮的简单图像之间的区别在于iframe 包含一个完整的网页 - 来自 Facebook。除了按钮和关于有多少人喜欢当前页面的信息外,此页面上没有太多内容。

因此,当您在 cnn.com 上看到“赞”按钮时,您实际上是在同时访问 Facebook 页面。这允许 Facebook 读取您计算机上的 cookie,该 cookie 在您上次登录 Facebook 时创建。

每个浏览器的基本安全规则是只有创建了 cookie 的网站才能稍后读取它。这就是 iframe 的优势:即使您正在访问不同的网站,它也允许 Facebook 读取您的 Facebook cookie。这就是他们在 cnn.com 上认出您并在那里显示您的朋友的方式。

来源:

  • 我认为 iframe 很少会被归类为做任何事情的最佳或最聪明的方式......但它是最简单的。 (8认同)
  • Facebook 域将无法访问父窗口 cookie,如果需要的话,它最多可以获取“window.parent.location”,但这并不重要,因为父窗口有意识地选择添加 facebook-iframe,它意味着在加载时 facebook 已经知道父页面标识符。基本上,父页面需要 Facebook 跟踪功能。在用户方面,要阻止它,需要一些浏览器扩展来阻止不需要的域,例如 Chrome 的 uBlock origin。 (2认同)

Dar*_*rov 25

没有跨域cookie这样的东西.你可以在foo.example.combar.example.com之间共享一个cookie ,但绝不会在example.com和之间共享一个cookie example2.com,这是出于安全原因.

  • 嗨,感谢您的回复,您能否在配置部分添加更多清晰度,如何在 j2ee 环境中创建/配置域和子域??? (2认同)
  • 这是一个更适合于 http://serverfault.com 的问题,您可以从该领域的专家那里获得答案。 (2认同)
  • 经常重复但不正确,请参阅下面或这里我的答案 http://stackoverflow.com/questions/16186645/cross-domain-cookies-a-maybe-new-idea (2认同)
  • 如何在foo.example.com和bar.example.com之间共享Cookie? (2认同)

The*_*Pea 20

在以下情况下允许跨站点 cookie :

  1. 设置cookie时:
    • Set-Cookie 响应报头包括SameSite=None; Secure如图这里这里
  2. 发送/接收cookie时:
    • 与跨域头,服务器的响应喜欢Access-Control-Allow-OriginAccess-Control-Allow-Credentials和请求与制作withCredentials:真正的,在其他的答案中提到这里,并在这里
  3. 一般来说:
    • 您的浏览器未禁用第 3 方 cookie。*

让我们澄清“域”与“站点”;对“URL 剖析”的快速提醒对我有帮助。在这个 URL 中https://example.com:8888/examples/index.html,记住这些主要部分(从这篇论文中得到):

  • “协议”: https://
  • “主机名/主机”: example.com
  • 港口”: 8888
  • “路径”:/examples/index.html

请注意用于 Cookie 目的的“路径”和“站点”之间的区别。“路径”是不是安全相关的; “站点”与安全相关:

小路

服务器可以在 中设置一个Path属性Set-Cookie,但它似乎与安全无关:

请注意,这path是为了性能,而不是安全性document.cookie即使路径不匹配,具有相同来源的网页仍然可以访问cookie 。

地点

根据web.dev 文章,SameSite 属性可以限制或允许跨站点 cookie;但什么是“网站”?

准确理解此处“站点”的含义会很有帮助。该站点是域后缀和它之前的域部分组合。例如,www.web.dev域是web.dev站点的一部分。

这意味着左边web.dev是一个子域;是的,www是子域(但子域是主机的一部分;请参阅此答案中的奖励回复

在此 URL 中https://www.example.com:8888/examples/index.html,请记住以下部分:

  • “协议”: https://
  • “主机名”又名“主机”: example.com
  • (在像“en.wikipedia.org”这样的情况下,整个“en.example.com”也是一个主机名
  • 港口”: 8888
  • 网站”: www.example.com
  • “域”: example.com
  • “子域”: www
  • 路径”: /examples/index.html

有用的链接:

小心;我正在 Chrome 隐身选项卡中测试我的功能;根据chrome://settings/cookies我的设置;我的设置是“在隐身模式中阻止第三方 cookie”,所以我无法在隐身模式中测试跨站点 cookie。)

浏览器打开 URL chrome://settings/cookies,显示“在隐身模式下阻止第三方 cookie”设置,在浏览器中选择允许第三方 cookie 的设置

  • 这不是跨域 cookie。没有什么比跨域 cookie 更好的了。这是一条你无法逃避的严格规则。页面 A 永远无法为页面 B 设置 cookie。您只是在源自页面 A 的页面 B 请求中发送页面 B 创建的 Cookie。 (6认同)
  • 这个答案清晰、彻底且有帮助。请注意,如果要使用凭据选项(对于 XMLHttpRequest 为“withCredentials”,对于 Fetch API 为“credentials”),“Access-Control-Allow-Origin”不能是通配符 (*) 值。[MDN 解释](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials)。在服务器上,您必须从传入请求中获取来源,并在“Access-Control-Allow-Origin”标头中返回该值。我不知道这从安全角度来说是好是坏。 (2认同)

Dan*_*erg 11

您不能跨域共享Cookie.但是,您可以允许所有子域具有访问权限.要允许所有子域example.com具有访问权限,请将域设置为.example.com.

但是不可能otherexample.com访问example.comcookie.

  • 如何在浏览YouTube时显示`.google.com` cookies? (25认同)
  • Google分析代码.这些cookie来自google.com,而不是来自youtube.com. (20认同)

Hos*_*ian 11

做谷歌正在做的事情.创建一个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>
Run Code Online (Sandbox Code Playgroud)

然后在body标签上添加onload回调.只有当图像完全加载时才会加载文档,即在其他2个域上设置cookie时.Onload回调:

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

setcookie.php
Run Code Online (Sandbox Code Playgroud)

我们使用这样的PHP文件在其他域上设置cookie:

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

现在cookie设置在三个域上.

  • 好,那么我们如何从另一个域读取? (3认同)
  • 如果启用了“阻止第三方Cookie”功能,则此功能无效。 (2认同)
  • 只是[另一个问题的另一个答案](/sf/answers/1368267631/)的复制粘贴。这个问题不存在“三域”。 (2认同)

Bry*_*cht 7

您可以尝试使用图像标记将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将不会设置.

  • 注意详细说明一点? (2认同)

小智 5

在nfriedly.com上有一个很好的概述Facebook如何做到这一点

还有浏览器指纹识别,它与cookie不同,但它的用途相似,它可以帮助您识别具有相当程度的确定性的用户.Stack Overflow上有一篇帖子引用了一种指纹识别方法