Cookie tra domini


247

Ho due webapp WebApp1 e WebApp2 in due domini diversi.

  1. Sto impostando un cookie in WebApp1 in HttpResponse.
  2. Come leggere lo stesso cookie da HttpRequest in WebApp2?

So che sembra strano perché i cookie sono specifici di un determinato dominio e non possiamo accedervi da domini diversi; Ho comunque sentito parlare di cookie CROSS-DOMAIN che possono essere condivisi su più webapp. Come implementare questo requisito usando i cookie CROSS-DOMAIN?

Nota: lo sto provando con le webapp J2EE

Risposte:


130

Sì, è assolutamente possibile ottenere i cookie da domain1.com da domain2.com. Ho avuto lo stesso problema per un social plugin del mio social network e dopo una giornata di ricerche ho trovato la soluzione.

Innanzitutto, sul lato server è necessario disporre delle seguenti intestazioni:

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

All'interno del file PHP è possibile utilizzare $_COOKIE[name]

In secondo luogo, sul lato client:

Nella richiesta Ajax è necessario includere 2 parametri

crossDomain: true
xhrFields: { withCredentials: true }

Esempio:

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

6
Oppure, se non desideri filtrare l'origine, utilizza $ _SERVER ['HTTP_ORIGIN'] invece di *
Joel Teply,

1
Questa è l'unica cosa che ha funzionato per me. Inoltre, * non è stato accettato come origine, quindi è necessario il suggerimento di @Joel Teply.
Indovinato il

4
Questo non funzionerà se i cookie di terze parti sono disabilitati (automatico per alcune situazioni del browser). Vedi blog.zok.pw/web/2015/10/21/3rd-party-cookies-in-practice e allannienhuis.com/archives/2013/11/03/… per ulteriori informazioni.
robocat,

4
Non usare punta di Joel, perché è "in sostanza" la stessa impostazione a "*", che può aprire falle di sicurezza sottili così è scoraggiato, vedere stackoverflow.com/questions/12001269/...
rogerdpack

5
sul lato server di quale dominio?
Nick Manning,

127

Come altri dicono, non puoi condividere i cookie, ma potresti fare qualcosa del genere:

  1. centralizzare tutti i cookie in un singolo dominio, diciamo cookiemaker.com
  2. quando l'utente invia una richiesta a example.com lo reindirizza a cookiemaker.com
  3. cookiemaker.com lo reindirizza su example.com con le informazioni di cui hai bisogno

Certo, non è completamente sicuro e devi creare un qualche tipo di protocollo interno tra le tue app per farlo.

Infine, sarebbe molto fastidioso per l'utente fare qualcosa del genere in ogni richiesta, ma non se fosse solo il primo.

Ma penso che non ci sia altro modo ...


44
Se non c'è altro modo, come funziona StackExchange / OpenID?
Hawken,

60
@Hawken StackExchange / OpenID segue lo stesso processo descritto sopra. Si viene reindirizzati a un sito diverso (SO> SX), si conferma la propria identità e quindi si reindirizza a SO con le informazioni necessarie. Le specifiche OpenID spiegano di più, sebbene Wikipedia lo faccia più chiaramente .
Nick Q.

1
Tutti gli utenti sono effettivamente connessi a cookiemaker.com. E reindirizza l'utente ai diversi siti con un messaggio speciale e sicuro che verifica che abbiano effettuato l'accesso e chi siano. Come implementarlo dipende da te, ci sono infiniti modi per farlo. Forse puoi usare questo: jwt.io
alcuadrado il

8
@ Andrew_1510 cookiebakersarebbe meglio ;-)
Richard Turner,

1
Ecco post con tag immagine, è una soluzione migliore ?
Shaijut,

70

Per quanto ne so, i cookie sono limitati dalla politica "stessa origine". Tuttavia, con CORS è possibile ricevere e utilizzare i cookie "Server B" per stabilire una sessione persistente da "Server A" su "Server B".

Tuttavia, ciò richiede alcune intestazioni sul "Server B":

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

E sarà necessario inviare il flag " withCredentials " a tutte le richieste "Server A" (es: xhr.withCredentials = true;)

Puoi leggerlo qui:

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

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


11
Questo non funzionerà per alcuni utenti perché i cookie CORS non funzioneranno se i cookie di terze parti sono disabilitati, ad esempio Safari per impostazione predefinita, ad esempio le impostazioni di Mozilla . Altri esempi di Google e un articolo sul perché Facebook non utilizza cookie di terze parti.
robocat,

1
Stack Exchange / OpenID utilizza CORS?
RayLoveless,

1
FWIW Ho appena testato un normale CORS con credenziali XHR e ha funzionato su FF / Safari / Chrome ... anche se non dubiterei che Facebook / Google utilizzino schemi più sofisticati
rogerdpack

30

Non esistono cookie tra domini. È possibile condividere un cookie tra foo.example.come bar.example.comma mai tra example.come example2.comper motivi di sicurezza.


1
Ciao grazie per la risposta, puoi per favore aggiungere più chiarezza sulla parte di configurazione, come creare / configurare dominio e sottodominio in ambiente j2ee ???
SundarJavaDeveloper,

1
Questa è una domanda che è più adatta a serverfault.com dove riceverai le risposte dagli esperti del dominio.
Darin Dimitrov,

Ciao, ho provato ad avere due webapp WebApp.domain.com ==> qui aggiungo cookie in quanto segue: Cookie cookie = nuovo Cookie ("namedCookie", "test"); cookie.setDomain ( "domain.com."); response.addCookie (cookie); WebApp1.domain.com ==> Qui ho provato ad accedere al cookie come segue, ma non riesco ad accedere a Cookie [] cks = request.getCookies (); for (int i = 0; i <cks.length; i ++) {out.print ("cookie trovato" + cks [i] .getValue ()); } Qualche idea su questo?
SundarJavaDeveloper,

2
spesso ripetuto ma non vero, vedi la mia risposta qui sotto o qui stackoverflow.com/questions/16186645/…
Raphael Jeger

4
Come condividere i cookie tra foo.example.come bar.example.com?
Jeff Tian,

24

La soluzione più intelligente è seguire il percorso di Facebook su questo. Come fa Facebook a sapere chi sei quando visiti un dominio? In realtà è molto semplice :

Il pulsante Mi piace in realtà consente a Facebook di tracciare tutti i visitatori del sito esterno, indipendentemente dal fatto che lo facciano o meno. Facebook può farlo perché utilizza un iframe per visualizzare il pulsante. Un iframe è qualcosa di simile a una finestra del browser incorporata all'interno di una pagina. La differenza tra l'utilizzo di un iframe e una semplice immagine per il pulsante è che l' iframe contiene una pagina web completa, da Facebook . Non c'è molto da fare in questa pagina, ad eccezione del pulsante e delle informazioni su quante persone hanno apprezzato la pagina corrente.

Quindi quando vedi un pulsante mi piace su cnn.com, stai effettivamente visitando una pagina Facebook allo stesso tempo. Ciò consente a Facebook di leggere un cookie sul tuo computer, che ha creato l'ultima volta che hai effettuato l'accesso a Facebook.

Una regola di sicurezza fondamentale in ogni browser è che solo il sito Web che ha creato un cookie può leggerlo in seguito. E questo è il vantaggio dell'iframe: consente a Facebook di leggere i cookie di Facebook anche quando si visita un sito Web diverso. È così che ti riconoscono su cnn.com e mostrano lì i tuoi amici.

Fonte:


6
Penso che un iframe si classifichi raramente come il modo migliore o più intelligente per fare qualsiasi cosa .. ma è il più semplice.
Orun,

13

Fai quello che sta facendo Google. Crea un file PHP che imposta il cookie su tutti e 3 i domini. Quindi sul dominio in cui verrà impostato il tema, crea un file HTML che carichi il file PHP che imposta i cookie sugli altri 2 domini. Esempio:

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

Quindi aggiungere un callback onload sul tag body. Il documento verrà caricato solo quando le immagini vengono caricate completamente, ovvero quando i cookie sono impostati sugli altri 2 domini. Ricarica onload:

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

setcookie.php

Impostiamo i cookie sugli altri domini utilizzando un file PHP come questo:

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

Ora i cookie sono impostati sui tre domini.


2
Questo non funziona se la funzione "Blocca cookie di terze parti" è abilitata.
Jens,

11

Non è possibile condividere i cookie tra domini. Puoi comunque consentire l'accesso a tutti i sottodomini. Per consentire a tutti i sottodomini di example.comavere accesso, impostare il dominio su .example.com.

Tuttavia , non è possibile dare otherexample.comaccesso ai example.comcookie.


27
come .google.commai vengono visualizzati i cookie quando si naviga su YouTube?
Hawken,

20
Tag di Google Analytics. Questi cookie provengono da google.com, non da youtube.com.
Entendu,

8

Puoi provare a spingere il cookie val in un altro dominio usando un tag immagine.

Il tuo chilometraggio può variare quando provi a farlo perché alcuni browser richiedono che tu abbia una corretta politica P3P sul dominio WebApp2 o il browser rifiuterà il cookie.

Se guardi alle norme p3p plus.google.com noterai che le loro norme sono:

CP = "Questa non è una norma P3P! Consulta http://www.google.com/support/accounts/bin/answer.py?hl=it&answer=151657 per ulteriori informazioni."

questa è la politica che usano per i loro pulsanti +1 per queste richieste tra domini.

Un altro avvertimento è che se sei su https assicurati che il tag immagine stia puntando a un indirizzo https, altrimenti i cookie non verranno impostati.


2
Ti interessa elaborare un po '?
frequente


1

Si possono usare iframe invisibili per ottenere i cookie. Diciamo che ci sono due domini, a.com e b.com. Per index.html del dominio a.com è possibile aggiungere (notare altezza = 0 larghezza = 0):

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

In questo modo il tuo sito Web riceverà i cookie di b.com supponendo che http://b.com imposti i cookie.

La prossima cosa sarebbe manipolare il sito all'interno dell'iframe tramite JavaScript. Le operazioni all'interno di iframe possono diventare una sfida se non si possiede il secondo dominio. Ma nel caso di avere accesso ad entrambi i domini che fanno riferimento alla pagina web corretta su src di iframe dovrebbe fornire i cookie che uno vorrebbe ottenere.


5
Solo un avvertimento: ci sono alcuni gravi problemi con i cookie negli iframe su Safari. Apparentemente non funzionano tra domini.
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

Includi origine dell'interfaccia utente e imposta Consenti credenziali su 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

Ho creato un modulo NPM che ti consente di condividere i dati archiviati localmente tra domini: https://www.npmjs.com/package/cookie-toss

Utilizzando un iframe ospitato sul dominio A, è possibile archiviare tutti i dati dell'utente sul dominio A e fare riferimento a tali dati inviando richieste all'iframe del dominio A.

Pertanto, i domini B, C, ecc. Possono iniettare l'iframe e inviargli richieste per archiviare e accedere ai dati desiderati. Il dominio A diventa l'hub per tutti i dati condivisi.

Con una whitelist di dominio all'interno del dominio A, puoi assicurarti che solo i tuoi siti dipendenti possano accedere ai dati sul dominio A.

Il trucco è avere il codice all'interno dell'iframe sul dominio A che è in grado di riconoscere quali dati vengono richiesti. Il file README nel modulo NPM sopra riportato approfondisce la procedura.

Spero che questo ti aiuti!


-4

Leggi Cookie inWeb 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;
                            }
                        }
                    }

Questo non gestisce la questione OP di utilizzare su due domini diversi
Niklas Wulff,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.