web-dev-qa-db-ja.com

クロスドメインクッキー

2つの異なるドメインに2つのWebアプリケーションWebApp1とWebApp2があります。

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

クッキーは特定のドメインに固有のものであり、異なるドメインからアクセスすることはできないため、奇妙に聞こえます。しかし、私は複数のWebアプリケーション間で共有できるCROSS-DOMAIN cookieについて聞いたことがあります。 CROSS-DOMAIN cookieを使用してこの要件を実装する方法

注:私はこれをJ2EE Webアプリケーションで試しています

201

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

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

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

最後に、すべてのリクエストでこのようなことをした場合、ユーザーにとって非常に面倒なことになりますが、それが最初のものだけではない場合があります。

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

114
alcuadrado

はい、domain2.comによってdomain1.comからクッキーを取得することは絶対に可能です。私は私のソーシャルネットワークのソーシャルプラグインについても同じ問題を抱えていました、そして研究の日の後に私は解決策を見つけました。

まず、サーバーサイドでは以下のヘッダが必要です。

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
}
104
Ludovic

私の知る限りでは、クッキーは「同一オリジン」ポリシーによって制限されています。ただし、CORSを使用すると、「サーバーB」上の「サーバーA」から永続セッションを確立するために「サーバーB」Cookieを受信して​​使用することができます。

ただし、これには「サーバーB」にいくつかのヘッダーが必要です。

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

そして、すべての "Server A"リクエストに "withCredentials"フラグを送る必要があります(例:xhr.withCredentials = true;

あなたはそれについてここで読むことができます:

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

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

62
Vitae Aliquam

クロスドメインクッキーのようなものはありません。 foo.example.combar.example.comの間でクッキーを共有することはできますが、example.comexample2.comの間では決して共有できません。これはセキュリティ上の理由からです。

22
Darin Dimitrov

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

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

setcookie.php

このようにPHPファイルを使用して他のドメインのクッキーを設定します。

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

現在、クッキーは3つのドメインに設定されています。

10

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

otherexample.comのクッキーへのアクセスをexample.comに与えることは不可能です。

8
Daniel Egeberg

画像タグを使用してcookie valを別のドメインにプッシュすることを試みることができます。

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

Plus.google.com p3pポリシーを見ると、そのポリシーは以下のとおりです。

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

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

もう1つの警告は、httpsを使用している場合は、画像タグがhttpsアドレスを指していることを確認してください。そうしないと、Cookieが設定されません。

7
Bryan Focht

Facebookがnfriedly.comでどのようにしてそれを成し遂げたか のまともな概要があります。

ブラウザフィンガープリントもあります。これはクッキーと同じではありませんが、かなり確実にユーザーを識別するのに役立ちます。フィンガープリントの1つの方法を参照する投稿があります ここではスタックオーバーフロー

5
byZero

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

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

だから、あなたがcnn.comにいいねボタンを見るとき、あなたは実際に同時にFacebookページを訪れています。これにより、Facebookは自分のコンピュータ上のCookieを読み取ることができます。これは、前回Facebookにログインしたときに作成されたものです。

すべてのブラウザの基本的なセキュリティルールは、クッキーを作成したWebサイトだけが後でそれを読むことができるということです。そしてそれはiframeの利点です:それはあなたが別のウェブサイトを訪れている時でさえもFacebookがあなたのFacebookクッキーを読むことを可能にします。そのようにして、彼らはcnn.comであなたを認識し、そこにあなたの友達を表示します。

ソース:

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
user7712621

目に見えないiframeを使ってクッキーを取得することができます。 a.comとb.comの2つのドメインがあるとしましょう。ドメインa.comのindex.htmlには次のものを追加できます(height = 0 width = 0に注意)。

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

そのようにあなたのウェブサイトはそれを仮定してb.comクッキーを取得するでしょう http://b.com クッキーを設定します。

次はJavaScriptを介してiframe内のサイトを操作することです。 2番目のドメインを所有していない場合、iframe内の操作は困難になる可能性があります。しかし、iframeのsrcにある正しいWebページを参照して両方のドメインにアクセスする場合は、取得したいcookieを指定する必要があります。

0
Vadym Tyemirov