Міждоменні файли cookie


247

У мене є два веб-сайти WebApp1 та WebApp2 у двох різних областях.

  1. Я встановлюю файл cookie в WebApp1 в HttpResponse.
  2. Як прочитати той самий файл cookie з HttpRequest в WebApp2?

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

Примітка. Я намагаюся це зробити з веб-сайтами J2EE

Відповіді:


130

Так, файл cookie з domain1.com абсолютно можливо отримати домен2.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
}

6
Або якщо ви не хочете фільтрувати походження, просто використовуйте $ _SERVER ['HTTP_ORIGIN'] замість *
Joel Teply

1
Це єдине, що працювало на мене. Крім того, * не було прийнято як джерело, тому потрібна порада @Joel Teply.
Здогадався

4
Це не працює, якщо сторонні файли cookie відключені (автоматичні для деяких ситуацій браузера). Для отримання додаткової інформації див. Blog.zok.pw/web/2015/10/21/3rd-party-cookies-in-practice та allannienhuis.com/archives/2013/11/03/… .
robocat

4
Не використовуйте кінчик Джоела, тому що «по суті» те ж саме, встановивши його на «*» , який може відкрити тонкі дірки в безпеці , так що відкидають , см stackoverflow.com/questions/12001269 / ...
rogerdpack

5
на сервері якого домену?
Нік Меннінг

127

Як кажуть інші люди, ви не можете ділитися файлами cookie, але ви можете зробити щось подібне:

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

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

Нарешті, користувачеві буде дуже дратувати, якщо ви робите щось подібне у кожному запиті, але не, якщо це лише перший.

Але я думаю, іншого шляху немає ...


44
Якщо іншого способу немає, то як StackExchange / OpenID працює?
Хоукен

60
@Hawken StackExchange / OpenID виконує той самий процес, що описаний вище. Ви спрямовуєтесь на інший сайт (SO> SX), підтверджуєте свою особу, а потім повертаєтесь до SO із необхідною інформацією. Спеціальність OpenID пояснює більше, хоча Вікіпедія робить це більш просто .
Нік Q.

1
Усі користувачі фактично увійшли в cookiemaker.com. І він перенаправляє користувача на різні сайти спеціальним та захищеним повідомленням, яке підтверджує, що вони увійшли та хто вони такі. Як це здійснити, залежить від вас, існує нескінченна кількість способів. Можливо, ви можете скористатись цим: jwt.io
alcuadrado

8
@ Andrew_1510 cookiebakerбуло б краще ;-)
Річард Тернер

1
Ось повідомлення з тегом зображення, це краще рішення ?
shaijut

70

Наскільки мені відомо, файли cookie обмежені політикою "того самого походження". Однак за допомогою CORS ви можете отримувати та використовувати файли cookie "Сервер B" для встановлення стійкого сеансу з "Сервера А" на "Сервер 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


11
Це не працює для деяких користувачів, оскільки файли cookie CORS не працюватимуть, якщо сторонні файли cookie відключені, наприклад Safari за замовчуванням, наприклад, параметри Mozilla . Google більше прикладів та стаття про те, чому Facebook не використовує сторонні файли cookie.
robocat

1
Чи обмін стеками / openID використовує CORS?
RayLoveless

1
FWIW Я щойно тестував звичайний CORS зCredentials XHR, і він працював на FF / Safari / Chrome ... хоча я б не сумнівався, що facebook / google використовує більш складні схеми
rogerdpack

30

Не існує такого поняття, як міждоменні файли cookie. Ви могли б поділитися печивом між foo.example.comі , bar.example.comале ніколи між example.comі example2.comі це з міркувань безпеки.


1
Привіт спасибі за відповідь, можете, будь ласка, додайте більше ясності в частині конфігурації, як створити / налаштувати домен та піддомен у j2ee середовищі ???
SundarJavaDeveloper

1
Це питання, більш адаптоване до serverfault.com, де ви отримаєте відповіді від експертів у цій галузі.
Дарин Димитров

Привіт, я спробував мати два веб-сайти WebApp.domain.com ==> тут я додаю cookie у відповідь так: Cookie cookie = new Cookie ("nameCookie", "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 знайдено" + cks [i] .getValue ()); } Будь-яка ідея з цього приводу?
SundarJavaDeveloper

2
часто повторюється, але не відповідає дійсності, дивіться мою відповідь нижче або тут stackoverflow.com/questions/16186645/…
Рафаель Джегер

4
Як ділитися файлами cookie між foo.example.comі bar.example.com?
Джефф Тіан

24

Найрозумніше рішення - це слідувати шляху Фейсбуку з цього приводу. Як фейсбук дізнається, хто ви є, коли відвідуєте будь-який домен? Насправді це дуже просто :

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

Тож, побачивши подібну кнопку на cnn.com, ви одночасно відвідуєте сторінку Facebook. Це дозволяє Facebook читати cookie на вашому комп’ютері, який він створив востаннє, коли ви ввійшли у Facebook.

Основне правило безпеки кожного браузера полягає в тому, що згодом може прочитати його лише веб-сайт, який створив файл cookie. І в цьому перевага iframe: вона дозволяє Facebook читати ваше Facebook-cookie навіть під час відвідування іншого веб-сайту. Ось як вони розпізнають вас на cnn.com та показують там ваших друзів.

Джерело:


6
Я думаю, що кадр рідко класифікується як найкращий чи найрозумніший спосіб зробити що-небудь .., але це найпростіший.
Орун

13

Робіть те, що робить Google. Створіть файл PHP, який встановлює файл cookie на всі 3 домени. Потім у домені, де буде встановлена ​​тема, створіть HTML-файл, який би завантажував файл PHP, який встановлює файли cookie для інших 2 доменів. Приклад:

<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. Документ завантажуватиметься лише тоді, коли зображення повністю завантажуються, коли файли cookie встановлені на інших двох доменах. Зворотний виклик при завантаженні:

<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);
}
?>

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


2
Це не працює, якщо включена функція "Блокувати файли cookie сторонніх сторін".
Єнс

11

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

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


27
як з'являються .google.comфайли cookie під час перегляду YouTube?
Хоукен

20
Теги Google Analytics. Ці файли cookie надходять з google.com, а не з youtube.com.
Ентенду

8

Ви можете спробувати перенести вал cookie на інший домен, використовуючи тег зображення.

При спробі зробити цей пробіг може змінюватися, оскільки деякі веб-переглядачі вимагають, щоб ви мали належну політику P3P щодо домену WebApp2, або браузер відкидає файл cookie.

Якщо ви подивитесь на політику plus.google.com p3p, ви побачите, що їх політика:

CP = "Це не політика P3P! Докладнішу інформацію див. На http://www.google.com/support/accounts/bin/answer.py?hl=uk&answer=151657 ."

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

Ще одне попередження: якщо ви перебуваєте на https, переконайтесь, що тег зображення вказує на https-адресу, інакше файли cookie не встановлять.


2
Хочете трохи допрацювати?
часті

5

Тут є гідний огляд того, як Facebook робить це на nfriedly.com

Існує також Відбитка пальців браузера, яка не є тотожкою cookie, але служить подібною метою, оскільки вона допомагає вам ідентифікувати користувача з достатньою визначеністю. Тут на сайті Stack Overflow є допис, що посилається на один метод відбитків пальців


1

Можна використовувати невидимі рамки для отримання файлів cookie. Скажімо, існує два домени - a.com та b.com. Для index.html домену a.com можна додати (висота повідомлення = 0 ширина = 0):

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

Таким чином ваш веб-сайт отримає файли cookie b.com, припускаючи, що http://b.com встановлює файли cookie.

Наступне - маніпулювати сайтом всередині iframe через JavaScript. Операції всередині iframe можуть стати викликом, якщо не належить другий домен. Але у випадку доступу до обох доменів, що посилаються на потрібну веб-сторінку в src iframe, слід надати файли cookie, які хотілося б отримати.


5
Лише попередження: Є кілька серйозних проблем із файлами cookie в iframes на Safari. Вони, мабуть, не працюють між доменами.
mvds

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

Включіть походження інтерфейсу користувача та встановіть для параметра Позволити Crentials істинно

<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

Використовуючи iframe, розміщений на Домені A, ви можете зберігати всі свої дані користувачів на Домені A і посилатись на ці дані, розміщуючи запити на iframe домену A.

Таким чином, домени B, C тощо можуть вводити в неї кадр iframe та надсилати запити для зберігання та доступу до потрібних даних. Домен A стає центром для всіх спільних даних.

За допомогою білого списку домену всередині Домену A ви можете забезпечити доступ до даних лише в домені А. лише залежним від вас сайтам.

Трюк полягає в тому, щоб у домені A був код всередині iframe, який може розпізнати, які дані запитуються. README у вищевказаному модулі NPM детальніше заглиблюється в процедуру.

Сподіваюсь, це допомагає!


-4

Читайте 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;
                            }
                        }
                    }

Це не вирішує питання використання
Ніклас Вульф,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.