Web Alanları Arası Tanımlama Bilgileri


247

İki farklı alanda iki webapps WebApp1 ve WebApp2 var.

  1. HttpResponse'deki WebApp1'de bir çerez ayarlıyorum.
  2. WebApp2'deki HttpRequest'ten aynı çerez nasıl okunur?

Kulağa garip geldiğini biliyorum çünkü çerezler belirli bir alana özgüdür ve onlara farklı alanlardan erişemiyoruz; Ancak birden çok web uygulamasında paylaşılabilen CROSS-DOMAIN çerezlerini duydum. Bu gereksinimi CROSS-DOMAIN çerezlerini kullanarak nasıl uygulayabilirim?

Not: Bunu J2EE webapps ile deniyorum

Yanıtlar:


130

Evet, çerezi domain2.com'dan domain1.com'dan almak kesinlikle mümkündür. Sosyal ağımın sosyal bir eklentisi için de aynı sorunu yaşadım ve bir günlük araştırmadan sonra çözümü buldum.

İlk olarak, sunucu tarafında aşağıdaki başlıklara sahip olmanız gerekir:

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 dosyasında şunları kullanabilirsiniz: $_COOKIE[name]

İkincisi, istemci tarafında:

Ajax isteğinize 2 parametre eklemeniz gerekir

crossDomain: true
xhrFields: { withCredentials: true }

Misal:

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

6
Veya orijini filtrelemek istemiyorsanız, * yerine $ _SERVER ['HTTP_ORIGIN'] kullanın
Joel Teply

1
Benim için işe yarayan tek şey bu. Ayrıca, * başlangıç ​​noktası olarak kabul edilmediğinden, @Joel Teply'nin ipucu gereklidir.
Guessed

4
Üçüncü taraf çerezleri devre dışı bırakılmışsa (bazı tarayıcı durumları için otomatik) bu çalışmaz. Daha fazla bilgi için blog.zok.pw/web/2015/10/21/3rd-party-cookies-in-practice ve allannienhuis.com/archives/2013/11/03/… adresine bakın .
robocat

4
Joel'in ipucunu kullanmayın, çünkü "özünde", küçük güvenlik açıklarını açabilecek ve bu yüzden cesaret
kırılmayacak

5
hangi etki alanının sunucu tarafında?
Nick Manning

127

Diğer insanların söylediği gibi, çerezleri paylaşamazsınız, ancak böyle bir şey yapabilirsiniz:

  1. tüm çerezleri tek bir alanda merkezileştirin, diyelim ki cookiemaker.com
  2. kullanıcı example.com'a bir istekte bulunduğunda onu cookiemaker.com'a yönlendirirsiniz
  3. cookiemaker.com, ihtiyacınız olan bilgilerle onu example.com'a geri yönlendirir

Tabii ki, tamamen güvenli değil ve bunu yapmak için uygulamalarınız arasında bir tür dahili protokol oluşturmanız gerekiyor.

Son olarak, her istekte böyle bir şey yaparsanız kullanıcı için çok can sıkıcı olurdu, ancak sadece birincisi değilse.

Ama bence başka yolu yok ...


44
Başka bir yol yoksa, StackExchange / OpenID nasıl çalışır?
Hawken

60
@ Hawken StackExchange / OpenID, yukarıda açıklanan işlemlerin aynısını izler. Farklı bir siteye yönlendirilirsiniz (SO> SX), kimliğinizi onaylarsınız ve ardından ihtiyacınız olan bilgilerle birlikte SO'ya yönlendirilirsiniz. OpenID Spec daha fazlasını açıklıyor, ancak Wikipedia daha açık bir şekilde yapıyor .
Nick Q.30

1
Tüm kullanıcılar aslında cookiemaker.com'da oturum açmıştır. Ve kullanıcıyı, oturum açtıklarını ve kim olduklarını doğrulayan özel ve güvenli bir mesajla farklı sitelere yönlendirir. Bunu nasıl uygulayacağınız size bağlıdır, bunu yapmanın sonsuz yolları vardır. Belki bunu kullanabilirsiniz: jwt.io
alcuadrado

8
@ Andrew_1510 cookiebakerdaha iyi olurdu ;-)
Richard Turner

1
İşte resim etiketi içeren yazı, daha iyi bir çözüm mü?
shaijut

70

Bildiğim kadarıyla, çerezler "aynı köken" politikası ile sınırlıdır. Ancak, CORS ile "Sunucu B" üzerindeki "Sunucu A" dan kalıcı bir oturum oluşturmak için "Sunucu B" çerezlerini alıp kullanabilirsiniz.

Bununla birlikte, bu "Sunucu B" üzerinde bazı üstbilgiler gerektirir:

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

Ve bayrak "göndermesi gerekir withCredentials tüm "Sunucu Bir" istekleri" (örn: xhr.withCredentials = true;)

Burada okuyabilirsiniz:

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

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


11
Bazı kullanıcılar için bu alışkanlık iş nedeniyle CORS çerezler olacak üçüncü taraf çerezleri örneğin devre dışı bırakılırsa değil iş varsayılan olarak Safari örneğin Mozilla ayarlarında . Google'a daha fazla örnek ve Facebook'un neden üçüncü taraf çerezlerini kullanmadığına dair bir makale .
robocat

1
Yığın değişimi / openID CORS kullanıyor mu?
RayLoveless

1
FWIW Sadece normal bir CORS withCredentials XHR'yi test ettim ve FF / Safari / Chrome üzerinde çalıştı ... ancak facebook / google'ın daha sofistike planlar kullandığından şüphe
etmem

30

Web alanları arası çerezler diye bir şey yoktur. Sen arasında bir çerez paylaşabilir foo.example.comve bar.example.comama asla arasındaki example.comve example2.comgüvenlik gerekçesiyle en söyledi.


1
Merhaba cevap için teşekkürler, u yapılandırma parçası, j2ee ortamında etki alanı ve alt alan adı oluşturma / yapılandırma hakkında daha fazla netlik ekleyebilir misiniz ???
SundarJavaDeveloper

1
Bu, alan adındaki uzmanlardan yanıtlar alacağınız serverfault.com'a daha fazla uyarlanmış bir sorudur .
Darin Dimitrov

Merhaba, ben iki webapps sahip WebApp.domain.com ==> denedim burada aşağıdaki gibi çerez eklemek: Cookie cookie = new Cookie ("namedCookie", "test"); cookie.setDomain ( "domain.com."); response.addCookie (tanımlama bilgisi); WebApp1.domain.com ==> Burada çereze aşağıdaki gibi erişmeye çalıştım, ancak Çerez [] 'e erişemiyorum cks = request.getCookies (); for (int i = 0; i <cks.length; i ++) {out.print ("çerez bulundu" + cks [i] .getValue ()); } Bu konuda bir fikrin var mı?
7:30

2
sık sık tekrarlanan ama doğru olmayan, cevabımı aşağıda veya burada görebilirsiniz stackoverflow.com/questions/16186645/…
Raphael Jeger

4
Nasıl arasındaki çerezleri paylaşmak foo.example.comve bar.example.com?
Jeff Tian

24

En akıllı çözüm, facebook'un bu konudaki yolunu takip etmektir. Herhangi bir alanı ziyaret ettiğinizde facebook kim olduğunuzu nasıl biliyor? Aslında çok basit :

Beğen düğmesi aslında Facebook'u tıklayıp tıklamasa da harici sitenin tüm ziyaretçilerini izlemesini sağlar. Facebook bunu yapabilir çünkü düğmeyi görüntülemek için bir iframe kullanırlar. İframe, bir sayfadaki gömülü tarayıcı penceresine benzer. Bir iframe ile düğme için basit bir resim kullanma arasındaki fark, iframe'in tam bir web sayfası içermesidir - Facebook'tan . Bu sayfada, düğme ve geçerli sayfayı kaç kişinin beğendiğiyle ilgili bilgiler dışında pek bir şey yok.

Yani cnn.com'da bir beğen düğmesi gördüğünüzde, aslında bir Facebook sayfasını aynı anda ziyaret ediyorsunuz. Bu, Facebook'un bilgisayarınızda son oturum açışınızda oluşturduğu bir çerezi okumasına olanak tanır.

Her tarayıcıda temel bir güvenlik kuralı, yalnızca bir çerez oluşturan web sitesinin daha sonra okuyabileceğidir. Bu iframe'in avantajı: Facebook'un farklı bir web sitesini ziyaret ettiğinizde bile Facebook çerezinizi okumasına izin veriyor. Sizi cnn.com'da böyle tanıyorlar ve arkadaşlarınızı orada sergiliyorlar.

Kaynak:


6
Bence bir iframe nadiren bir şey yapmanın en iyi ya da en akıllı yolu olarak sınıflandırılır .. ama en kolayı budur.
Orun

13

Google'ın yaptığını yapın. Çerezi 3 alanda da ayarlayan bir PHP dosyası oluşturun. Ardından, temanın ayarlanacağı etki alanında, diğer 2 alanda çerez ayarlayan PHP dosyasını yükleyecek bir HTML dosyası oluşturun. Misal:

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

Ardından gövde etiketine bir yüklenen geri arama ekleyin. Belge yalnızca görüntüler tamamen yüklendiğinde, yani diğer 2 alanda çerez ayarlandığında yüklenir. Yüklü Geri Arama:

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

setcookie.php

Aşağıdaki gibi bir PHP dosyası kullanarak diğer alanlardaki çerezleri ayarladık:

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

Şimdi çerezler üç alanda ayarlanmıştır.


2
'Üçüncü taraf çerezlerini engelle' özelliği etkinse bu çalışmaz.
Jens

11

Alan adlarında çerezleri paylaşamazsınız. Ancak, tüm alt alan adlarının erişmesine izin verebilirsiniz. Sitesinin tüm alt alan adlarına example.comerişim izni vermek için alan adını olarak ayarlayın .example.com.

'S çerezlerine otherexample.comerişim vermek mümkün değil example.com.


27
.google.comYouTube'a göz atarken çerezler nasıl ortaya çıkıyor ?
Hawken

20
Google analiz etiketleri. Bu çerezler youtube.com'dan değil google.com'dan gelir.
Entendu

8

Bir resim etiketi kullanarak çerez valini başka bir alana itmeyi deneyebilirsiniz.

Bazı tarayıcılar WebApp2 etki alanında uygun bir P3P Politikasına sahip olmanızı gerektirdiğinden veya tarayıcı çerezi reddedeceğinden, bunu yapmaya çalışırken kilometreniz değişebilir .

Plus.google.com p3p politikasına bakarsanız, politikalarının olduğunu göreceksiniz:

CP = "Bu bir P3P politikası değil! Daha fazla bilgi için http://www.google.com/support/accounts/bin/answer.py?hl=tr&answer=151657 adresine bakın ."

bu etki alanları arası isteklerde +1 düğmelerinde kullandıkları politikadır.

Başka bir uyarı, https'deyseniz, resim etiketinin bir https adresine işaret ettiğinden emin olun, aksi takdirde çerezler ayarlanmaz.


2
Biraz özen göstermek ister misiniz?
sık sık


1

Çerezleri almak için görünmez iframe'ler kullanılabilir. Diyelim ki iki alan var, a.com ve b.com. A.com etki alanının index.html'si için (uyarı yüksekliği = 0 genişlik = 0) eklenebilir:

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

Bu şekilde, web siteniz http://b.com çerezleri ayarladığını varsayarak b.com çerezleri alır.

Bir sonraki şey iframe içindeki siteyi JavaScript aracılığıyla değiştirmek olacaktır. İframe içindeki işlemler, ikinci alan adına sahip değilse bir meydan okuma haline gelebilir. Ancak, iframe'in src'sinde doğru web sayfasına atıfta bulunan her iki alana erişim olması durumunda, almak istediğiniz çerezleri vermelidir.


5
Sadece bir uyarı: Safari'deki iframe'lerde çerezlerle ilgili bazı ciddi sorunlar var. Görünüşe göre alanlar arası çalışmıyorlar.
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

Kullanıcı arabirimi kaynağını dahil et ve Kimlik Bilgilerine İzin Ver'i doğru olarak ayarla

<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

Yerel olarak depolanan verileri etki alanlarında paylaşmanıza olanak tanıyan bir NPM modülü oluşturdum: https://www.npmjs.com/package/cookie-toss

Alan A'da barındırılan bir iframe kullanarak, tüm kullanıcı verilerinizi Alan A'da depolayabilir ve Alan A iframe'ine istek göndererek bu verilere başvurabilirsiniz.

Böylece, B, C, vb. Alanları, iframe'i enjekte edebilir ve istenen verileri depolamak ve erişmek için kendisine istek gönderebilir. Alan A, tüm paylaşılan verilerin merkezi haline gelir.

Alan A'nın içindeki bir alan beyaz listesiyle Alan A'daki verilere yalnızca bağımlı sitelerinizin erişmesini sağlayabilirsiniz.

İşin püf noktası, Alan A'daki iframe'in içinde hangi verilerin talep edildiğini tanıyabilen bir kod bulundurmaktır. Yukarıdaki NPM modülündeki README, işleme daha derinlemesine bakar.

Bu yardımcı olur umarım!


-4

oku Cookie içindeWeb 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;
                            }
                        }
                    }

Bu OP'nin iki farklı alanda kullanım sorusunu ele almıyor
Niklas Wulff
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.