クロスドメインCookie


247

2つの異なるドメインに2つのwebapps WebApp1とWebApp2があります。

  1. HttpResponseのWebApp1にCookieを設定しています。
  2. WebApp2のHttpRequestから同じCookieを読み取る方法は?

Cookieは特定のドメインに固有であり、異なるドメインからはアクセスできないため、奇妙に聞こえるかもしれません。ただし、複数のWebアプリケーション間で共有できるCROSS-DOMAIN Cookieについて聞いたことがあります。CROSS-DOMAIN Cookieを使用してこの要件を実装するにはどうすればよいですか?

注:私はJ2EE webappsでこれを試しています

回答:


130

はい、domain2.comによってdomain1.comからCookieを取得することは絶対に可能です。私のソーシャルネットワークのソーシャルプラグインにも同じ問題があり、1日の調査の結果、解決策を見つけました。

まず、サーバー側では次のヘッダーが必要です。

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
}

6
または、オリジンでフィルタリングしたくない場合は、*の代わりに$ _SERVER ['HTTP_ORIGIN']を使用します
Joel Teply

1
これは私のために働いた唯一のものです。また、*はオリジンとして受け入れられなかったため、@ Joel Teplyのヒントが必要です。
15

4
これは、サードパーティのCookieが無効になっている場合は機能しません(ブラウザの状況によっては自動)。詳細については、blog.zok.pw / web / 2015/10/21 / 3rd -party-cookies-in-practiceおよびallannienhuis.com/archives/2013/11/03/…を参照してください。
robocat 2016

4
それは、とても落胆している微妙なセキュリティホールを開く見ることができる「*」に設定するのと同じ「本質的に」あるので、ジョエルの先端を使用しないでくださいstackoverflow.com/questions/12001269/...
rogerdpack

5
どのドメインのサーバー側ですか?
Nick Manning、

127

他の人が言うように、あなたはクッキーを共有することはできませんが、あなたはこのようなことをすることができます:

  1. すべてのCookieを単一のドメインに集中化します。たとえば、cookiemaker.comとしましょう
  2. ユーザーがexample.comにリクエストを送信すると、cookiemaker.comにリダイレクトされます
  3. cookiemaker.comは、必要な情報を使用してexample.comにリダイレクトします。

もちろん、完全に安全ではありません。そのためには、アプリ間に何らかの内部プロトコルを作成する必要があります。

最後に、すべてのリクエストでそのようなことをするのはユーザーにとって非常に煩わしいですが、それが最初のリクエストである場合はそうではありません。

しかし、他に方法はないと思います...


44
他に方法がない場合、StackExchange / OpenIDはどのように機能しますか?
Hawken、2012年

60
@Hawken StackExchange / OpenIDは、上記と同じプロセスに従います。別のサイト(SO> SX)にリダイレクトされ、身元を確認すると、必要な情報が記載されたSOにリダイレクトされます。OpenID Specはより詳しく説明していますが、ウィキペディアはより分かりやすく説明しています
Nick Q.

1
すべてのユーザーは実際にcookiemaker.comにログインしています。また、ユーザーがログインしていることとユーザーが誰であるかを確認する特別で安全なメッセージを使用して、ユーザーを別のサイトにリダイレクトします。それを実装する方法はあなた次第です、そうするための無限の方法があります。多分あなたはこれを使うことができます:jwt.io
alcuadrado

8
@ Andrew_1510のcookiebaker方が良いでしょう;-)
リチャードターナー

1
ここに画像タグ付きの投稿がありますが、それはより良い解決策ですか?
shaijut 16

70

私の知る限り、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/en/tutorials/cors/

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


11
一部のユーザーのために、この文句を言わない作業CORSクッキーが動作しませんので、サードパーティのCookieが無効になっ例えばある場合、デフォルトでのSafariなどのMozillaの設定。グーグルの他の例FacebookがサードパーティのCookieを使用しない理由に関する記事
robocat 2016

1
スタック交換/ openIDはCORSを使用しますか?
RayLoveless 2016年

1
FWIW私は通常のCORS withCredentials XHRをテストしましたが、FF / Safari / Chromeで動作しました... facebook / googleがより洗練されたスキームを使用していることは間違いありません
rogerdpack

30

クロスドメインCookieなどはありません。あなたは間のクッキーを共有することができfoo.example.comそしてbar.example.com決して間example.comexample2.comし、セキュリティ上の理由のこと。


1
こんにちは返信に感謝します。j2ee環境でドメインとサブドメインを作成/構成する方法、構成の部分をもっと明確にしていただけますか???
SundarJavaDeveloper 2010

1
これは、ドメインの専門家から回答を得るserverfault.comにより適した質問です。
Darin Dimitrov 2010

こんにちは、私は2つのwebapps WebApp.domain.comを試してみました==>ここで、次のようにRESPOSEにCookieを追加します。Cookie Cookie = new Cookie( "namedCookie"、 "test"); cookie.setDomain( "。domain.com"); response.addCookie(cookie); WebApp1.domain.com ==>ここでは、次のようにCookieにアクセスしようとしましたが、Cookie [] cks = request.getCookies();にアクセスできません。for(int i = 0; i <cks.length; i ++){out.print( "cookie found" + cks [i] .getValue()); これについて何か考えはありますか?
SundarJavaDeveloper 2010

2
頻繁に繰り返さなく、真のは、ここの下に私の答えを参照するか、stackoverflow.com/questions/16186645/...
ラファエルJeger

4
間のクッキーを共有する方法foo.example.comとはbar.example.com
ジェフ・ティエン

24

最も賢い解決策は、これに関するFacebookのパスに従うことです。Facebookはどのドメインにアクセスしたときにあなたが誰であるかをどのようにして知るのですか それは実際には非常に簡単です:

「いいね!」ボタンを使用すると、Facebookは外部サイトのすべての訪問者を、クリックしたかどうかに関係なく追跡できます。Facebookはiframeを使用してボタンを表示するため、これを行うことができます。iframeは、ページ内に埋め込まれたブラウザウィンドウのようなものです。iframeを使用する場合とボタンに単純な画像を使用する場合の違いは、iframeにFacebookの完全なWebページが含まれていることです。このページでは、ボタンと現在のページを気に入った人の数に関する情報を除いて、それほど多くのことは行われていません。

したがって、cnn.comに「いいね!」ボタンが表示されている場合は、実際には同時にFacebookページにアクセスしています。これにより、Facebookはコンピューター上のCookieを読み取ることができます。これは、ユーザーが最後にFacebookにログインしたときに作成されたCookieです。

すべてのブラウザの基本的なセキュリティルールは、Cookieを作成したWebサイトだけが後でそれを読み取ることができるということです。これがiframeの利点です。別のWebサイトにアクセスしている場合でも、FacebookはFacebookのCookieを読み取ることができます。それは彼らがcnn.comであなたを認識し、そこにあなたの友達を表示する方法です。

ソース:


6
iframeが何かを行うための最善または最も賢い方法として分類されることはめったにないと思いますが、それが最も簡単です。
Orun 2018

13

Googleがやっていることを実行します。3つのドメインすべてにCookieを設定するPHPファイルを作成します。次に、テーマを設定するドメインで、他の2つのドメインにCookieを設定するPHPファイルをロードするHTMLファイルを作成します。例:

<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コールバックを追加します。ドキュメントが読み込まれるのは、画像が完全に読み込まれたとき、つまりCookieが他の2つのドメインに設定されたときだけです。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が3つのドメインに設定されました。


2
「サードパーティのCookieをブロックする」機能が有効になっている場合、これは機能しません。
イェンス2016

11

ドメイン間でCookieを共有することはできません。ただし、すべてのサブドメインにアクセスを許可することができます。のすべてのサブドメインにexample.comアクセスを許可するには、ドメインをに設定します.example.com

ただし、のCookie otherexample.comへのアクセスを許可することはできませんexample.com


27
どのように来.google.comその後、YouTubeに閲覧したときにクッキーが現れ?
Hawken

20
Googleアナリティクスタグ。これらのCookieは、youtube.comではなくgoogle.comから取得されます。
Entendu 2013

8

イメージタグを使用して、Cookieの値を別のドメインにプッシュすることができます。

一部のブラウザーではWebApp2ドメインに適切なP3Pポリシーを設定する必要があるか、ブラウザーがCookieを拒否するため、これを実行しようとすると走行距離が異なる場合があります。

plus.google.comのp3pポリシーを見ると、それらのポリシーは次のとおりであることがわかります。

CP = "これはP3Pポリシーではありません!詳細は、http://www.google.com/support/accounts/bin/answer.py?hl = ja&answer = 151657を参照してください。"

それは、これらのクロスドメインリクエストへの+1ボタンに使用するポリシーです。

別の警告は、httpsを使用している場合は、イメージタグがhttpsアドレスを指していることを確認してください。それ以外の場合は、Cookieが設定されません。


2
少し詳しく説明しますか?
頻繁


1

非表示のiframeを使用してCookieを取得できます。a.comとb.comの2つのドメインがあるとします。ドメインa.comのindex.htmlの場合、次のように追加できます(高さ= 0幅= 0に注意):

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

これにより、http: //b.comがCookieを設定すると想定して、Webサイトはb.com Cookieを取得します。

次に、JavaScriptを使用してiframe内のサイトを操作します。iframe内の操作は、2番目のドメインを所有していない場合、困難になる可能性があります。ただし、両方のドメインにアクセスできる場合は、iframeのソースで正しいWebページを参照すると、取得したいCookieが提供されます。


5
単なる警告:SafariのiframeのCookieにはいくつかの深刻な問題があります。彼らは明らかにクロスドメインで動作しません。
mvds 2013

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オリジンを含め、資格情報を許可を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>

1

ローカルに保存されているデータをドメイン間で共有できるようにするNPMモジュールを作成しました:https : //www.npmjs.com/package/cookie-toss

ドメインAでホストされているiframeを使用すると、すべてのユーザーデータをドメインAに保存し、ドメインAのiframeにリクエストを送信してそのデータを参照できます。

したがって、ドメインB、Cなどは、iframeを挿入し、要求をポストして、目的のデータを格納およびアクセスできます。ドメインAは、すべての共有データのハブになります。

ドメインA内のドメインホワイトリストを使用すると、依存サイトのみがドメインAのデータにアクセスできるようにすることができます。

トリックは、要求されているデータを認識できるドメインAのiframe内にコードを置くことです。上記のNPMモジュールのREADMEは、手順をさらに詳しく説明しています。

お役に立てれば!


-4

読ん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;
                            }
                        }
                    }

これは、2つの異なるドメインに使用したのOPの質問処理しない
ニクラス・ヴルフ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.