Cookie Lintas Domain

247

Saya memiliki dua webapps WebApp1 dan WebApp2 dalam dua domain berbeda.

  1. Saya menetapkan cookie di WebApp1 di HttpResponse.
  2. Bagaimana cara membaca cookie yang sama dari HttpRequest di WebApp2?

Saya tahu kedengarannya aneh karena cookie khusus untuk domain yang diberikan, dan kami tidak dapat mengaksesnya dari domain yang berbeda; Namun saya pernah mendengar tentang cookie CROSS-DOMAIN yang dapat dibagikan di beberapa webapps. Bagaimana cara menerapkan persyaratan ini menggunakan cookie CROSS-DOMAIN?

Catatan: Saya mencoba ini dengan webapp J2EE

Pengembang SundarJava
sumber

Jawaban:

130

Ya, sangat mungkin untuk mendapatkan cookie dari domain1.com oleh domain2.com. Saya memiliki masalah yang sama untuk plugin sosial di jejaring sosial saya, dan setelah seharian melakukan penelitian, saya menemukan solusinya.

Pertama, di sisi server Anda harus memiliki header berikut:

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

Dalam file PHP yang dapat Anda gunakan $_COOKIE[name]

Kedua, di sisi klien:

Dalam permintaan ajax Anda, Anda perlu memasukkan 2 parameter

crossDomain: true
xhrFields: { withCredentials: true }

Contoh:

type: "get",
url: link,
crossDomain: true,
dataType: 'json',
xhrFields: {
  withCredentials: true
}
Ludovic
sumber
6
Atau jika Anda tidak ingin memfilter pada asalnya, cukup gunakan $ _SERVER ['HTTP_ORIGIN'] alih-alih *
Joel Teply
1
Ini adalah satu-satunya hal yang berhasil untuk saya. Juga, * tidak diterima sebagai asal, jadi tip @ Joel Teply diperlukan.
Tebak
4
Ini tidak akan berfungsi jika cookie pihak ketiga dinonaktifkan (otomatis untuk beberapa situasi browser). Lihat blog.zok.pw/web/2015/10/21/3rd-party-cookies-in-practice dan allannienhuis.com/archives/2013/11/03/… untuk informasi lebih lanjut.
robocat
4
Jangan gunakan tip Joel, karena itu "pada dasarnya" sama dengan mengaturnya ke "*" yang dapat membuka lubang keamanan halus sehingga tidak disarankan, lihat stackoverflow.com/questions/12001269/…
rogerdpack
5
di sisi server dari domain mana?
Nick Manning
127

Seperti yang orang lain katakan, Anda tidak dapat membagikan cookie, tetapi Anda dapat melakukan sesuatu seperti ini:

  1. memusatkan semua cookie dalam satu domain, katakanlah cookiemaker.com
  2. ketika pengguna membuat permintaan ke example.com Anda mengarahkannya ke cookiemaker.com
  3. cookiemaker.com mengalihkannya kembali ke example.com dengan informasi yang Anda butuhkan

Tentu saja, itu tidak sepenuhnya aman, dan Anda harus membuat semacam protokol internal antara aplikasi Anda untuk melakukannya.

Terakhir, akan sangat mengganggu bagi pengguna jika Anda melakukan hal seperti itu di setiap permintaan, tetapi tidak jika itu hanya yang pertama.

Tapi saya pikir tidak ada cara lain ...

alcuadrado
sumber
44
Jika tidak ada cara lain, lalu bagaimana cara kerja StackExchange / OpenID?
Hawken
60
@Hawken StackExchange / OpenID mengikuti proses yang sama seperti yang dijelaskan di atas. Anda diarahkan ke situs lain (SO> SX), konfirmasikan identitas Anda, dan kemudian diarahkan kembali ke SO dengan informasi yang Anda butuhkan. OpenID Spec menjelaskan lebih banyak, meskipun Wikipedia melakukannya dengan lebih jelas .
Nick Q.
1
Semua pengguna benar-benar masuk ke cookiemaker.com. Dan itu mengarahkan pengguna ke situs yang berbeda dengan pesan khusus dan aman yang memverifikasi bahwa mereka masuk dan siapa mereka. Bagaimana menerapkannya terserah Anda, ada cara tak terbatas untuk melakukannya. Mungkin Anda bisa menggunakan ini: jwt.io
alcuadrado
8
@ Andrew_1510 cookiebakerakan lebih baik ;-)
Richard Turner
1
Ini posting dengan tag gambar, apakah itu solusi yang lebih baik ?
shaijut
70

Sejauh yang saya tahu, cookie dibatasi oleh kebijakan "asal sama". Namun, dengan CORS Anda dapat menerima dan menggunakan cookie "Server B" untuk membuat sesi persisten dari "Server A" pada "Server B".

Meskipun, ini memerlukan beberapa tajuk di "Server B":

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

Dan Anda harus mengirim tanda " withCredentials " pada semua permintaan "Server A" (mis:xhr.withCredentials = true; )

Anda dapat membacanya di sini:

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

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

Vitae Aliquam
sumber
11
Ini tidak akan berfungsi untuk beberapa pengguna karena cookie CORS tidak akan berfungsi jika cookie pihak ketiga dinonaktifkan, misalnya Safari secara default, misalnya pengaturan Mozilla . Google lebih banyak contoh dan artikel tentang mengapa Facebook tidak menggunakan cookie pihak ketiga.
robocat
1
Apakah stack exchange / openID menggunakan CORS?
Ray tanpa cinta
1
FWIW Saya baru saja menguji CORS normal dengan Kredensial XHR dan berhasil pada FF / Safari / Chrome ... walaupun saya tidak akan ragu bahwa facebook / google menggunakan skema yang lebih canggih
rogerdpack
30

Tidak ada yang namanya cookie lintas domain. Anda dapat membagikan cookie antara foo.example.comdan bar.example.comtetapi tidak pernah antara example.comdan example2.comdan itu untuk alasan keamanan.

Darin Dimitrov
sumber
1
Hai terima kasih atas jawabannya, dapatkah Anda menambahkan lebih banyak kejelasan pada bagian konfigurasi, cara membuat / mengkonfigurasi domain dan subdomain di lingkungan j2ee ???
SundarJavaDeveloper
1
Ini adalah pertanyaan yang lebih disesuaikan dengan serverfault.com di mana Anda akan mendapatkan jawaban dari para ahli di domain.
Darin Dimitrov
Hai, saya mencoba memiliki dua webapps WebApp.domain.com ==> di sini saya menambahkan cookie sebagai berikut: Cookie cookie = Cookie baru ("namedCookie", "test"); cookie.setDomain (". domain.com"); response.addCookie (cookie); WebApp1.domain.com == Di sini saya mencoba mengakses cookie sebagai berikut, tetapi tidak dapat mengakses Cookie [] cks = request.getCookies (); untuk (int i = 0; i <cks.length; i ++) {out.print ("cookie ditemukan" + cks [i] .getValue ()); } Ada ide tentang ini?
SundarJavaDeveloper
2
sering diulang tetapi tidak benar, lihat jawaban saya di bawah ini atau di sini stackoverflow.com/questions/16186645/…
Raphael Jeger
4
Bagaimana cara membagi cookie antara foo.example.comdan bar.example.com?
Jeff Tian
24

Solusi paling cerdas adalah mengikuti jalur facebook dalam hal ini. Bagaimana facebook tahu siapa Anda saat Anda mengunjungi domain apa pun? Ini sebenarnya sangat sederhana :

Tombol Suka sebenarnya memungkinkan Facebook untuk melacak semua pengunjung situs eksternal, tidak peduli apakah mereka mengkliknya atau tidak. Facebook dapat melakukannya karena mereka menggunakan iframe untuk menampilkan tombol. Iframe adalah sesuatu seperti jendela peramban yang disematkan di dalam suatu halaman. Perbedaan antara menggunakan iframe dan gambar sederhana untuk tombol adalah iframe berisi halaman web lengkap - dari Facebook . Tidak banyak yang terjadi di halaman ini, kecuali tombol dan informasi tentang berapa banyak orang menyukai halaman saat ini.

Jadi ketika Anda melihat tombol suka di cnn.com, Anda sebenarnya mengunjungi halaman Facebook secara bersamaan. Itu memungkinkan Facebook untuk membaca cookie di komputer Anda, yang telah dibuatnya terakhir kali Anda masuk ke Facebook.

Aturan keamanan mendasar di setiap browser adalah bahwa hanya situs web yang telah membuat cookie yang dapat membacanya nanti. Dan itulah keuntungan dari iframe: memungkinkan Facebook untuk membaca cookie Facebook Anda bahkan ketika Anda mengunjungi situs web yang berbeda. Begitulah cara mereka mengenali Anda di cnn.com dan menampilkan teman-teman Anda di sana.

Sumber:

Morteza Shahriari Nia
sumber
6
Saya pikir iframe jarang akan digolongkan sebagai cara terbaik atau paling cerdas untuk melakukan apa pun .. tetapi itu adalah yang termudah.
Orun
13

Lakukan apa yang dilakukan Google. Buat file PHP yang menetapkan cookie di ketiga domain. Kemudian pada domain tempat tema akan diatur, buat file HTML yang akan memuat file PHP yang menetapkan cookie pada 2 domain lainnya. Contoh:

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

Kemudian tambahkan callback onload pada tag tubuh. Dokumen hanya akan memuat ketika gambar benar-benar dimuat yaitu ketika cookie diatur pada 2 domain lainnya. Onback Callback:

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

setcookie.php

Kami menetapkan cookie pada domain lain menggunakan file PHP seperti ini:

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

Sekarang cookie diatur pada tiga domain.

Hossain Khademian
sumber
2
Ini tidak berfungsi jika fitur 'Blokir cookie pihak ketiga' diaktifkan.
Jens
11

Anda tidak dapat membagikan cookie di seluruh domain. Namun Anda dapat mengizinkan semua subdomain untuk memiliki akses. Untuk mengizinkan semua subdomain example.commemiliki akses, setel domain ke .example.com.

Namun tidak mungkin memberikan otherexample.comakses ke example.comcookie.

Daniel Egeberg
sumber
27
bagaimana bisa .google.comcookie muncul saat menjelajah ke YouTube?
Hawken
20
Tag analitik Google. Cookie tersebut berasal dari google.com, bukan dari youtube.com.
Entendu
8

Anda dapat mencoba untuk mendorong val cookie ke domain lain menggunakan tag gambar.

Jarak tempuh Anda mungkin berbeda ketika mencoba melakukan ini karena beberapa browser mengharuskan Anda memiliki Kebijakan P3P yang tepat pada domain WebApp2 atau browser akan menolak cookie.

Jika Anda melihat kebijakan p3p plus.google.com Anda akan melihat bahwa kebijakan mereka adalah:

CP = "Ini bukan kebijakan P3P! Lihat http://www.google.com/support/accounts/bin/answer.py?hl=id&answer=151657 untuk info lebih lanjut."

itu adalah kebijakan yang mereka gunakan untuk tombol +1 mereka untuk permintaan lintas domain ini.

Peringatan lain adalah bahwa jika Anda menggunakan https pastikan bahwa tag gambar mengarah ke alamat https juga jika tidak, cookie tidak akan ditetapkan.

Bryan Focht
sumber
2
Mau sedikit menguraikan?
sering
1

Orang dapat menggunakan iframe yang tidak terlihat untuk mendapatkan cookie. Katakanlah ada dua domain, a.com dan b.com. Untuk index.html domain a.com orang dapat menambahkan (perhatikan tinggi = 0 lebar = 0):

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

Dengan begitu situs web Anda akan mendapatkan cookie b.com dengan asumsi bahwa http://b.com menetapkan cookie.

Hal berikutnya adalah memanipulasi situs di dalam iframe melalui JavaScript. Operasi di dalam iframe dapat menjadi tantangan jika seseorang tidak memiliki domain kedua. Tetapi jika memiliki akses ke kedua domain merujuk halaman web yang tepat di src iframe harus memberikan cookie yang ingin Anda dapatkan.

Vadym Tyemirov
sumber
5
Hanya peringatan: Ada beberapa masalah serius dengan cookie di iframe di Safari. Mereka tampaknya tidak bekerja lintas domain.
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

Sertakan asal UI dan setel Perbolehkan Crentials menjadi 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>
pengguna7712621
sumber
1

Saya telah membuat modul NPM, yang memungkinkan Anda untuk berbagi data yang disimpan secara lokal di seluruh domain: https://www.npmjs.com/package/cookie-toss

Dengan menggunakan iframe yang dihosting di Domain A, Anda dapat menyimpan semua data pengguna Anda di Domain A, dan referensi data itu dengan memposting permintaan ke iframe Domain A.

Dengan demikian, Domain B, C, dll. Dapat menyuntikkan iframe dan mengirim permintaan kepadanya untuk menyimpan dan mengakses data yang diinginkan. Domain A menjadi hub untuk semua data bersama.

Dengan daftar putih domain di dalam Domain A, Anda dapat memastikan hanya situs dependen Anda yang dapat mengakses data di Domain A.

Kuncinya adalah memiliki kode di dalam iframe di Domain A yang dapat mengenali data mana yang diminta. README dalam modul NPM di atas masuk lebih dalam ke prosedur.

Semoga ini membantu!

jmealy
sumber
-4

Baca Cookie masukWeb 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;
                            }
                        }
                    }
pengguna7712621
sumber
Ini tidak menangani pertanyaan OP tentang penggunaan pada dua domain yang berbeda
Niklas Wulff