Междоменные куки - PullRequest
201 голосов
/ 27 июля 2010

У меня есть два веб-приложения WebApp1 и WebApp2 в двух разных доменах.

  1. Я устанавливаю cookie в WebApp1 в HttpResponse.
  2. Как прочитать тот же cookie из HttpRequest вWebApp2?

Я знаю, это звучит странно, потому что файлы cookie относятся к конкретному домену, и мы не можем получить к ним доступ из разных доменов;Однако я слышал о cookie-файлах CROSS-DOMAIN, которые могут использоваться несколькими веб-приложениями.Как реализовать это требование с помощью файлов cookie CROSS-DOMAIN?

Примечание. Я пытаюсь это сделать с помощью веб-приложений J2EE

Ответы [ 12 ]

113 голосов
/ 27 июля 2010

Как говорят другие люди, вы не можете делиться файлами cookie, но вы можете сделать что-то вроде этого:

  1. централизует все куки в одном домене, скажем cookiemaker.com
  2. когда пользователь отправляет запрос на example.com, вы перенаправляете его на cookiemaker.com
  3. cookiemaker.com перенаправляет его обратно на example.com с необходимой информацией

Конечно, это не совсем безопасно, и для этого вам нужно создать какой-то внутренний протокол между вашими приложениями.

Наконец, пользователю будет очень неприятно, если вы будете делать что-то подобное в каждом запросе, но не в том случае, если это будет только первый.

Но я думаю, что другого пути нет ...

104 голосов
/ 16 сентября 2014

Да, абсолютно возможно получить cookie от domain1.com от domain2.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
}
62 голосов
/ 06 апреля 2013

Насколько я знаю, cookie-файлы ограничены политикой "одного и того же происхождения". Однако с помощью CORS вы можете получать и использовать файлы cookie «Сервер B» для установки постоянного сеанса с «Сервер А» на «Сервер Б».

Хотя для этого требуются некоторые заголовки на «сервере 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

23 голосов
/ 27 июля 2010

Междоменных файлов cookie не существует. Вы можете поделиться cookie между foo.example.com и bar.example.com, но не между example.com и example2.com, и это по соображениям безопасности.

10 голосов
/ 01 декабря 2014

Делай то, что делает Google. Создайте файл PHP, который устанавливает cookie на всех 3 доменах. Затем в домене, где будет установлена ​​тема, создайте файл HTML, который будет загружать файл PHP, который устанавливает cookie в двух других доменах. Пример:

<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>

Затем добавьте обратный вызов onload для тега body. Документ будет загружаться только тогда, когда изображения полностью загружаются, то есть когда файлы cookie установлены на двух других доменах. Onload Callback:

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

setcookie.php

Мы устанавливаем файлы cookie в других доменах, используя файл PHP следующим образом:

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

Теперь куки установлены на трех доменах.

8 голосов
/ 27 июля 2010

Вы не можете делиться файлами cookie между доменами. Однако вы можете разрешить доступ ко всем поддоменам. Чтобы разрешить доступ всем поддоменам example.com, установите для домена значение .example.com.

Невозможно предоставить otherexample.com доступ к файлам cookie example.com.

7 голосов
/ 09 января 2014

Вы можете попытаться отправить cookie val в другой домен, используя тег изображения.

Ваш пробег может варьироваться при попытке сделать это, потому что некоторые браузеры требуют, чтобы у вас была правильная Политика P3P в домене WebApp2, иначе браузер отклонит cookie.

Если вы посмотрите на политику p.gp plus.google.com, вы увидите, что их политика:

CP = "Это не политика P3P! Для получения дополнительной информации см. http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657."

это политика, которую они используют для своих кнопок +1 к этим междоменным запросам.

Еще одно предупреждение: если вы находитесь на https, убедитесь, что тег изображения указывает на адрес https, иначе файлы cookie не будут установлены.

5 голосов
/ 21 февраля 2012

Достаточно краткий обзор того, как Facebook делает это здесь, на nfriedly.com

Также есть «Отпечатки пальцев» в браузере, которые не совпадают с cookie, но служат аналогичной цели в этомэто поможет вам идентифицировать пользователя с достаточной степенью уверенности.Здесь есть сообщение о переполнении стека , которое ссылается на один метод снятия отпечатков пальцев

1 голос
/ 07 июня 2018

Самое разумное решение - следовать по пути Facebook. Как Facebook узнает, кто вы, когда посещаете какой-либо домен? Это на самом деле очень просто :

Кнопка «Мне нравится» фактически позволяет Facebook отслеживать всех посетителей внешнего сайта, независимо от того, нажимают они на них или нет. Facebook может сделать это, потому что для отображения кнопки используется iframe . Iframe - это что-то вроде встроенного окна браузера на странице. Разница между использованием iframe и простого изображения для кнопки заключается в том, что iframe содержит полную веб-страницу - из Facebook . На этой странице ничего особенного не происходит, кроме кнопки и информации о том, как много людей понравилась текущая страница.

Поэтому, когда вы видите кнопку «Мне нравится» на cnn.com, вы одновременно посещаете страницу Facebook. Это позволяет Facebook читать файл cookie на вашем компьютере, который был создан при последнем входе в Facebook.

Фундаментальное правило безопасности в каждом браузере заключается в том, что только веб-сайт, создавший cookie-файл, может прочитать его позже. И это является преимуществом iframe: он позволяет Facebook читать ваш файл cookie Facebook, даже когда вы посещаете другой веб-сайт. Так они узнают вас на cnn.com и показывают там ваших друзей.

Источник:

1 голос
/ 15 марта 2017
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

Включить происхождение пользовательского интерфейса и установить для параметра Разрешить 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>
...