도메인 간 쿠키


247

두 개의 다른 도메인에 두 개의 webapps WebApp1과 WebApp2가 있습니다.

  1. HttpResponse의 WebApp1에서 쿠키를 설정하고 있습니다.
  2. WebApp2의 HttpRequest에서 동일한 쿠키를 읽는 방법은 무엇입니까?

쿠키는 특정 도메인에만 적용되고 다른 도메인에서 쿠키에 액세스 할 수 없기 때문에 이상하게 들립니다. 그러나 여러 웹 응용 프로그램에서 공유 할 수있는 CROSS-DOMAIN 쿠키에 대해 들었습니다. CROSS-DOMAIN 쿠키를 사용하여이 요구 사항을 구현하는 방법은 무엇입니까?

참고 : J2EE webapps로 시도하고 있습니다.

답변:


130

예, domain2.com을 통해 domain1.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의 팁이 필요합니다.
20:14에

4
타사 쿠키가 비활성화 된 경우 (일부 브라우저 상황에서는 자동으로) 작동하지 않습니다. 자세한 내용은 blog.zok.pw/web/2015/10/21/3rd-party-cookies-in-practiceallannienhuis.com/archives/2013/11/03/… 을 참조하십시오.
robocat 2019

4
Joel의 팁은 "본질적으로"미묘한 보안 허점을 열 수 있으므로 "*"로 설정하는 것과 동일하므로 사용하지 마십시오. stackoverflow.com/questions/12001269/…
rogerdpack

5
어느 도메인의 서버 쪽에서?
Nick Manning

127

다른 사람들이 말했듯이 쿠키를 공유 할 수는 없지만 다음과 같이 할 수 있습니다.

  1. 단일 도메인에서 모든 쿠키를 중앙 집중화하십시오. cookiemaker.com
  2. 사용자가 example.com에 요청하면 cookiemaker.com으로 리디렉션합니다.
  3. cookiemaker.com은 필요한 정보를 사용하여 그를 example.com으로 다시 리디렉션합니다.

물론, 완전히 안전하지는 않으므로 앱간에 일종의 내부 프로토콜을 만들어야합니다.

마지막으로, 모든 요청에서 이와 같은 작업을 수행하면 사용자에게는 매우 성가신 일이지만 첫 번째 경우는 아닙니다.

그러나 다른 방법은 없다고 생각합니다 ...


44
다른 방법이 없다면 StackExchange / OpenID는 어떻게 작동합니까?
Hawken

60
@Hawken StackExchange / OpenID는 위에서 설명한 것과 동일한 프로세스를 따릅니다. 다른 사이트 (SO> SX)로 이동하여 신원을 확인한 다음 필요한 정보를 사용하여 SO로 다시 이동합니다. Wikipedia가 더 명확하게 설명하지만 OpenID 사양에 대해 더 자세히 설명합니다 .
Nick Q.

1
모든 사용자는 실제로 cookiemaker.com에 로그인되어 있습니다. 또한 사용자가 로그인했는지, 누가 있는지 확인하는 특별하고 안전한 메시지를 통해 사용자를 다른 사이트로 리디렉션합니다. 그것을 구현하는 방법은 당신에게 달려 있으며, 그렇게하는 무한한 방법이 있습니다. 아마 당신은 이것을 사용할 수 있습니다 : jwt.io
alcuadrado

8
@ Andrew_1510 cookiebaker이 더 좋을 것입니다 ;-)
Richard Turner

1
여기 이미지 태그가있는 게시물이 더 나은 솔루션 입니까?
shaijut

70

내가 아는 한 쿠키는 "동일한 출처"정책에 의해 제한됩니다. 그러나 CORS를 사용하면 "서버 B"쿠키를 받고 사용하여 "서버 B"의 "서버 A"에서 영구 세션을 설정할 수 있습니다.

그러나 "서버 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
일부 사용자에게이 늘 일 때문에 CORS 쿠키 것이다 타사 쿠키 등을 사용할 수 없습니다 아닌 경우 작업 기본적으로 사파리 예를 들어 모질라 설정 . Facebook에서 타사 쿠키를 사용하지 않는 이유에 대한 Google의 더 많은 예제기사
robocat 2019

1
스택 교환 / openID는 CORS를 사용합니까?
RayLoveless 2016 년

1
FWIW 난 그냥 일반 CORS withCredentials XHR 테스트는 ... FF / 사파리 / 크롬에 근무하지만 나는 것없는 의심 페이스 북 / 사용보다 정교한 계획을 구글 있음
rogerdpack

30

도메인 간 쿠키와 같은 것은 없습니다. 당신은 사이에 쿠키를 공유 할 수 foo.example.combar.example.com하지만 결코 사이 example.comexample2.com보안상의 이유로의 것을.


1
답장을 보내 주셔서 감사합니다. u 구성 부분에 명확성을 더 추가 할 수 있습니까, 어떻게 j2ee 환경에서 도메인 및 하위 도메인을 생성 / 구성합니까?
SundarJavaDeveloper

1
이것은 도메인의 전문가로부터 답변을 얻을 수있는 serverfault.com에보다 적합한 질문입니다 .
Darin Dimitrov

안녕하세요, 두 개의 webapps WebApp.domain.com ==>을 시도했는데 다음과 같이 respose에 쿠키를 추가합니다. Cookie cookie = new Cookie ( "namedCookie", "test"); cookie.setDomain ( ". domain.com"); response.addCookie (쿠키); WebApp1.domain.com ==> 여기서 쿠키에 다음과 같이 액세스하려고했지만 쿠키에 액세스 할 수 없습니다 [] cks = request.getCookies (); for (int i = 0; i <cks.length; i ++) {out.print ( "cookie found"+ cks [i] .getValue ()); } 이것에 대한 아이디어가 있습니까?
SundarJavaDeveloper

2
종종 반복되지만 사실은 아닙니다. 아래 또는 여기의 답변을 참조하십시오 stackoverflow.com/questions/16186645/…
Raphael Jeger 12

4
foo.example.com와 사이에 쿠키를 공유하는 방법 bar.example.com?
Jeff Tian

24

가장 현명한 해결책은 페이스 북의 경로를 따르는 것입니다. 도메인을 방문 할 때 페이스 북은 당신이 누구인지 어떻게 알 수 있습니까? 실제로 매우 간단합니다 .

좋아요 버튼을 클릭하면 Facebook은 클릭 여부에 상관없이 외부 사이트의 모든 방문자를 추적 할 수 있습니다. Facebook은 iframe 을 사용 하여 버튼을 표시 하기 때문에 그렇게 할 수 있습니다 . iframe은 페이지 내의 내장 브라우저 윈도우와 유사합니다. iframe과 버튼에 간단한 이미지를 사용하는 것의 차이점은 iframe에 Facebook의 완전한 웹 페이지가 포함되어 있다는 것 입니다. 이 페이지에는 버튼과 현재 페이지를 좋아 한 사람 수에 대한 정보를 제외하고는 계속 진행되지 않습니다.

따라서 cnn.com에 like 버튼이 표시되면 실제로 Facebook 페이지를 방문하는 것입니다. 이를 통해 Facebook은 컴퓨터에서 쿠키를 읽을 수 있으며 이는 마지막으로 Facebook에 로그인했을 때 생성 된 쿠키입니다.

모든 브라우저의 기본 보안 규칙은 쿠키를 만든 웹 사이트 만 나중에 읽을 수 있다는 것입니다. 이는 iframe의 장점입니다. 다른 웹 사이트를 방문 할 때도 Facebook에서 Facebook 쿠키를 읽을 수 있습니다. 그들이 cnn.com에서 당신을 인식하고 거기에 친구를 표시하는 방법입니다.

출처:


6
iframe이 가장 좋은 방법이나 가장 똑똑한 방법으로 분류되는 경우는 거의 없다고 생각합니다. 그러나 가장 쉬운 방법입니다.
Orun

13

Google이하는 일을하십시오. 3 개의 도메인 모두에 쿠키를 설정하는 PHP 파일을 만듭니다. 그런 다음 테마를 설정할 도메인에서 다른 두 도메인에 쿠키를 설정하는 PHP 파일을로드하는 HTML 파일을 작성하십시오. 예:

<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 태그에 onload 콜백을 추가하십시오. 문서는 이미지가 완전히로드 될 때, 즉 다른 두 도메인에 쿠키가 설정된 경우에만로드됩니다. 부하시 콜백 :

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

setcookie.php

다음과 같은 PHP 파일을 사용하여 다른 도메인에 쿠키를 설정합니다.

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

이제 쿠키가 세 도메인에 설정되었습니다.


2
'타사 쿠키 차단'기능이 활성화 된 경우 작동하지 않습니다.
Jens

11

도메인간에 쿠키를 공유 할 수 없습니다. 그러나 모든 하위 도메인에 액세스 권한을 부여 할 수 있습니다. 모든 하위 도메인에 example.com액세스 할 수있게하려면 도메인을.example.com .

의 쿠키에 otherexample.com대한 액세스 권한을 부여 할 수는 없습니다 example.com.


27
.google.com그러면 YouTube를 탐색 할 때 쿠키가 어떻게 표시됩니까?
Hawken

20
Google 웹 로그 분석 태그 이러한 쿠키는 youtube.com이 아닌 google.com에서 제공됩니다.
Entendu

8

이미지 태그를 사용하여 쿠키 값을 다른 도메인으로 푸시 할 수 있습니다.

일부 브라우저는 적절한 P3P 정책 을 요구하기 때문에 마일리지가 변경 될 수 있습니다 WebApp2 도메인에 하거나 브라우저가 쿠키를 거부 .

plus.google.com p3p 정책을 보면 해당 정책이 다음과 같습니다.

CP = "P3P 정책이 아닙니다. 자세한 내용은 http://www.google.com/support/accounts/bin/answer.py?hl=ko&answer=151657 을 참조 하십시오 ."

이것이 교차 도메인 요청에 대한 +1 버튼에 사용되는 정책입니다.

또 다른 경고는 https를 사용하는 경우 이미지 태그가 https 주소를 가리키고 있는지 확인하면 쿠키가 설정되지 않는다는 것입니다.


2
조금 정교하게 관리?
자주


1

보이지 않는 iframe을 사용하여 쿠키를 얻을 수 있습니다. a.com과 b.com이라는 두 개의 도메인이 있다고 가정 해 봅시다. 도메인 a.com의 index.html에 다음을 추가 할 수 있습니다 (고지 높이 = 너비 = 0).

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

그렇게하면 http://b.com 이 쿠키를 설정 한다고 가정하면 웹 사이트에서 b.com 쿠키를 얻게 됩니다.

다음은 JavaScript를 통해 iframe 내부의 사이트를 조작하는 것입니다. iframe 내부의 작업이 두 번째 도메인을 소유하지 않으면 문제가 될 수 있습니다. 그러나 iframe의 src에서 올바른 웹 페이지를 참조하는 두 도메인에 액세스 할 경우 쿠키를 가져와야합니다.


5
경고 : Safari의 iframe 쿠키에 심각한 문제가 있습니다. 도메인 간 작동하지 않는 것 같습니다.
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

UI 오리진 포함 및 신임 정보 허용을 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

도메인간에 로컬로 저장된 데이터를 공유 할 수있는 NPM 모듈을 만들었습니다. https://www.npmjs.com/package/cookie-toss

도메인 A에서 호스팅되는 iframe을 사용하면 모든 사용자 데이터를 도메인 A에 저장하고 도메인 A iframe에 요청을 게시하여 해당 데이터를 참조 할 수 있습니다.

따라서 도메인 B, C 등은 iframe을 주입하고 요청을 게시하여 원하는 데이터를 저장하고 액세스 할 수 있습니다. 도메인 A는 모든 공유 데이터의 허브가됩니다.

도메인 A 내부의 도메인 화이트리스트를 사용하면 종속 사이트 만 도메인 A의 데이터에 액세스 할 수 있습니다.

요령은 요청 된 데이터를 인식 할 수있는 도메인 A의 iframe 내부에 코드를 작성하는 것입니다. 위의 NPM 모듈의 README는 절차에 대해 더 자세히 설명합니다.

도움이 되었기를 바랍니다!


-4

읽기 CookieWeb 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;
                            }
                        }
                    }

이것은 두 개의 다른 도메인에서 사용하는 OP 질문을 다루지 않습니다
Niklas Wulff
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.