web-dev-qa-db-fra.com

Cookies interdomaines

J'ai deux WebApps WebApp1 et WebApp2 dans deux domaines différents.

  1. Je crée un cookie dans WebApp1 dans HttpResponse.
  2. Comment lire le même cookie à partir de HttpRequest dans WebApp2?

Je sais que cela semble étrange car les cookies sont spécifiques à un domaine donné et nous ne pouvons pas y accéder depuis différents domaines. J'ai toutefois entendu parler de cookies CROSS-DOMAIN qui peuvent être partagés entre plusieurs applications Web. Comment mettre en œuvre cette exigence à l'aide de cookies CROSS-DOMAIN?

Remarque: j'essaie ceci avec les applications Web J2EE

207
SundarJavaDeveloper

Comme d'autres personnes le disent, vous ne pouvez pas partager de cookies, mais vous pouvez faire quelque chose comme ceci:

  1. centraliser tous les cookies dans un seul domaine, disons cookiemaker.com
  2. lorsque l'utilisateur fait une demande à example.com, vous le redirigez vers cookiemaker.com
  3. cookiemaker.com le redirige vers example.com avec les informations dont vous avez besoin

Bien sûr, ce n'est pas complètement sécurisé et vous devez créer un protocole interne entre vos applications pour le faire.

Enfin, il serait très gênant pour l'utilisateur si vous faites quelque chose comme ça dans chaque requête, mais pas si c'est juste la première.

Mais je pense qu'il n'y a pas d'autre moyen ...

117
alcuadrado

Oui, il est absolument possible d’obtenir le cookie de domain1.com par domain2.com. J'ai eu le même problème pour un plugin social de mon réseau social, et après une journée de recherche, j'ai trouvé la solution.

Premièrement, côté serveur, vous devez avoir les en-têtes suivants:

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, *");

Dans le fichier PHP, vous pouvez utiliser $_COOKIE[name]

Deuxièmement, du côté du client:

Dans votre demande ajax, vous devez inclure 2 paramètres.

crossDomain: true
xhrFields: { withCredentials: true }

Exemple:

type: "get",
url: link,
crossDomain: true,
dataType: 'json',
xhrFields: {
  withCredentials: true
}
108
Ludovic

Autant que je sache, les cookies sont limités par la politique de "même origine". Cependant, avec CORS, vous pouvez recevoir et utiliser les cookies "Serveur B" pour établir une session persistante à partir du "Serveur A" sur le "Serveur B".

Bien que cela nécessite quelques en-têtes sur "Serveur B":

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

Et vous devrez envoyer l'indicateur " withCredentials " sur toutes les demandes du "Serveur A" (ex: xhr.withCredentials = true;)

Vous pouvez lire à ce sujet ici:

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

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

65
Vitae Aliquam

Les cookies entre domaines n'existent pas. Vous pouvez partager un cookie entre foo.example.com et bar.example.com mais jamais entre example.com et example2.com et ceci pour des raisons de sécurité.

23
Darin Dimitrov

Faites ce que Google fait. Créez un fichier PHP qui définit le cookie sur les 3 domaines. Ensuite, sur le domaine où le thème va être défini, créez un fichier HTML qui chargerait le fichier PHP qui définit le cookie sur les 2 autres domaines. Exemple:

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

Ajoutez ensuite un rappel onload sur la balise body. Le document ne se chargera que lorsque les images seront complètement chargées, c'est-à-dire lorsque les cookies seront configurés sur les 2 autres domaines. Rappel en charge:

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

setcookie.php

Nous définissons les cookies sur les autres domaines en utilisant un fichier PHP comme ceci:

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

Maintenant, les cookies sont installés sur les trois domaines.

11
Hossain Khademian

Vous ne pouvez pas partager de cookies entre domaines. Vous pouvez toutefois autoriser l'accès à tous les sous-domaines. Pour autoriser l'accès à tous les sous-domaines de example.com, définissez le domaine sur .example.com.

Il n'est pas possible de donner à otherexample.com l'accès aux cookies de example.com.

10
Daniel Egeberg

Vous pouvez essayer de transmettre la valeur du cookie à un autre domaine à l'aide d'une balise d'image.

Votre kilométrage peut varier lorsque vous essayez de le faire, car certains navigateurs exigent que vous ayez un Politique P3P correct sur le domaine WebApp2, sinon le navigateur rejettera le cookie.

Si vous consultez la règle plus.google.com, la stratégie p3p vous indique que leur stratégie est la suivante:

CP = "Ceci n'est pas une politique P3P! Voir http://www.google.com/support/accounts/bin/answer.py?hl=fr&answer=151657 pour plus d'informations."

c'est la politique qu'ils utilisent pour leurs boutons +1 à ces demandes interdomaines.

Un autre avertissement est que si vous êtes sur https, assurez-vous que la balise image pointe vers une adresse https, sinon les cookies ne seront pas configurés.

7
Bryan Focht

Il y a un bon aperçu de comment Facebook le fait ici sur nfriedly.com

Il existe également une empreinte de navigateur, qui n’est pas la même chose qu’un cookie, mais sert un objectif similaire en ce sens qu’elle vous aide à identifier un utilisateur avec un degré de certitude suffisant. Il y a un article ici sur Stack Overflow qui fait référence à une méthode d'empreinte digitale

5
byZero

La solution la plus intelligente est de suivre le chemin de Facebook à ce sujet. Comment Facebook sait-il qui vous êtes lorsque vous visitez un domaine? C'est en fait très simple :

Le bouton J'aime permet en réalité à Facebook de suivre tous les visiteurs du site externe, qu'ils cliquent ou non. Facebook peut le faire car ils utilisent un iframe pour afficher le bouton. Un iframe est quelque chose comme une fenêtre de navigateur intégrée dans une page. La différence entre l'utilisation d'un iframe et d'une image simple pour le bouton est que l'iframe contient une page Web complète - à partir de Facebook . Il n'y a pas beaucoup d'activités sur cette page, à l'exception du bouton et des informations sur le nombre de personnes qui ont aimé la page en cours.

Ainsi, lorsque vous voyez un bouton "J'aime" sur cnn.com, vous visitez en même temps une page Facebook. Cela permet à Facebook de lire un cookie sur votre ordinateur, qu'il a créé la dernière fois que vous vous êtes connecté à Facebook.

Une règle de sécurité fondamentale dans chaque navigateur est que seul le site Web qui a créé un cookie peut le lire ultérieurement. Et c'est l'avantage de l'iframe: il permet à Facebook de lire votre cookie Facebook même lorsque vous visitez un site Web différent. C’est comme ça qu’ils vous reconnaissent sur cnn.com et y affichent vos amis.

La source:

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

Inclure l'origine de l'interface utilisateur et définir Autoriser les informations d'identification à 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

On peut utiliser des iframes invisibles pour obtenir les cookies. Disons qu'il y a deux domaines, a.com et b.com. Pour le fichier index.html du domaine a.com, vous pouvez ajouter (remarque height = 0 width = 0):

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

Ainsi, votre site Web obtiendra les cookies b.com en supposant que http://b.com configure les cookies.

La prochaine chose serait de manipuler le site dans l'iframe via JavaScript. Les opérations à l'intérieur d'iframe peuvent devenir un défi si l'on ne possède pas le deuxième domaine. Toutefois, si vous avez accès aux deux domaines en vous référant à la bonne page Web à l'adresse src de iframe, vous devez fournir les cookies souhaités.

0
Vadym Tyemirov