Programing

Safari에서 교차 도메인 쿠키 설정

crosscheck 2020. 12. 9. 07:50
반응형

Safari에서 교차 도메인 쿠키 설정


도메인 B.com에서 도메인 A.com (http로 쿠키를 설정하는)을 호출해야합니다. 도메인 B.com에서 내가하는 일은 (자바 스크립트)입니다.

var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = "A.com/setCookie?cache=1231213123";
head.appendChild(script);

이렇게하면 Safari를 제외한 모든 브라우저에서 A.com의 쿠키가 설정됩니다. 놀랍게도 이것은 P3P 헤더 없이도 IE6에서 작동합니다.

Safari에서이 작업을 수행 할 수있는 방법이 있습니까?


에서 Safari Developer FAQ:

Safari는 사용자가 선택한 ( "탐색 된") 페이지에만 쿠키 쓰기를 제한하는 보수적 인 쿠키 정책과 함께 제공됩니다. 이 기본 보수적 정책은 쿠키 작성을 시도하고 실패하는 프레임 기반 사이트를 혼동 할 수 있습니다.

이 문제를 해결할 방법을 찾지 못했습니다.

가치가 있다면 Chrome은 <script> 추가 방법 을 사용하는 경우에도 쿠키를 설정하지 않지만 <img동일한 소스를 가진 숨겨진 >가있는 경우 Chrome은 나머지 브라우저 (다시 말하지만 Safari 제외)와 함께 작동합니다.


다음은 작동하는 솔루션입니다.

http://anantgarg.com/2010/02/18/cross-domain-cookies-in-safari/


작업 방법 2014-2016 :

도메인에 window.open / 쿠키 할당 / 팝업 닫기를 수행해야 도메인이 이제 허용 목록에 있습니다.

iPad / iPhone 브라우저에서 작동하지 않는 PHP 다중 쿠키의 원본 게시물


플래시가 설치되어 있다고 가정하는 사악한 트릭이 있습니다.

여전히 작동하는지 여부는 확실하지 않지만 Flash의 "로컬 공유 객체"(일명 Flash 쿠키) 는 Safari의 동일한 도메인 정책을 우회하는 데 도움이 될 수 있습니다.

로컬 공유 객체 튜토리얼

그러나 최소한 구현하는 것은 복잡 할 수 있습니다.

또한 LSO는 보안 악몽으로 밝혀지고 있습니다.

따라서 사용하기 전에 신중하게 생각하십시오.


숨겨진 게시물을 <iframe>사용하면 Safari에서이 제한을 우회 할 수 있습니다 . http://gist.github.com/586182 :

<?php
  header('P3P: CP=HONK');
  setcookie('test_cookie', '1', 0, '/');
?>
<div id="test_cookie" style="position: absolute; top: -10000px"></div>
<script>
  window.setTimeout(function() {
    if (document.cookie.indexOf('test_cookie=1') < 0) {
      var      
        name = 'test_cookie',
        div = document.getElementById(name),
        iframe = document.createElement('iframe'),
        form = document.createElement('form');

      iframe.name = name;
      iframe.src = 'javascript:false';
      div.appendChild(iframe);

      form.action = location.toString();
      form.method = 'POST';
      form.target = name;
      div.appendChild(form);

      form.submit();
    }
  }, 10);
</script>

2015 년에이 작업에 대한 적절한 해결 방법이 있습니다. 사이트 x.com이있는 iframe을 포함하는 웹 사이트 y.com이 있다고 가정 해 보겠습니다. x.com iframe은 쿠키를 저장하려고합니다. 이는 Safari 정책에서 허용되지 않지만 y.com은이를 저장할 수 있습니다. 따라서 y.com은 x.com의 메시지를 수신 한 다음 쿠키 자체를 저장해야합니다.

var _cookieEvMth = window.addEventListener ? "addEventListener" : "attachEvent";
var _cookieEvAction = window[_cookieEvMth];
var _cookieEv = _cookieEvMth == "attachEvent" ? "onmessage" : "message";
_cookieEvAction(_cookieEv, function(evt){
  if(evt.data.indexOf('cookieset')!=-1){
    var datack = evt.data.split('|');
    YOUR_CUSTOM_COOKIE_SAVE_METHOD(datack[1],datack[2],datack[3]);
  }
},false);

x.com에서 쿠키를 저장해야하는 경우 y.com에 메시지를 게시해야합니다.

window.parent.postMessage('cookieset|'+ckName+'|'+ckVal+'|'+days,'*');

또한 쿠키를 읽고 싶다면 iframe에 메시지를 게시하는 방법을 사용할 수 있습니다. 또는 javascript를 사용하여 x.com iframe URL에 매개 변수로 포함 할 수 있습니다.

iframe.setAttribute('url','x.com/?cookieval='+YOUR_COOKIE_GET_METHOD('cookiename'));

제 일에서 우리가 방금 생각 해낸 해결 방법은 window.open ()을 통해 쿠키를 설정하는 것이 었습니다. 이것은 당신에게 최적이 아닐 수도 있지만 . 어쨌든 OAuth 인증을 위해 팝업 창을 열어야했습니다.

그래서 우리가 한 일의 요지는 :

  1. 사용자가 B.com에서 링크를 클릭합니다.
  2. A.com/setCookie에 팝업 창이 열립니다.
  3. A.com은 쿠키를 설정 한 다음 적절한 위치에있는 B.com으로 리디렉션합니다.

다시 말하지만 모든 솔루션에서 유효하지는 않지만 우리 솔루션에서는 작동했습니다. 도움이 되었기를 바랍니다.


이 질문이 다소 오래되었다는 것을 알고 있지만 이것은 쿠키 문제를 해결하는 데 도움이되었습니다.

var cookieForm = document.createElement("form");
cookieForm.action = "A.com/setCookie?cache=1231213123";
cookieForm.method = "post";
document.body.appendChild(cookieForm);

cookieForm.submit();

쿠키를 설정하는 페이지에 양식 게시물을 만드는 아이디어.


* 편집 * 이 해결 방법은 WebKit에서 종료 된 것으로보고되었습니다.

루카,

좋아요,이 답변은 2 년 전이지만 ... 양식을 숨겨진 iframe에 게시하면 iframe에서 쿠키를 설정할 수 있습니다. 양식을 작성하여이를 수행 할 수 있습니다.

<form id="myiframe" action="http://yourdomain.com" method="POST" target="iframe_target">

그런 다음 Javascript에서 양식에 대한 참조를 가져오고 submit을 호출하십시오.

document.getElementsByTagName('form')[0].submit();

iframe의 온로드를 듣거나 iframe 작업 페이지에서로드를 알리는 자바 스크립트를 발행하도록 할 수 있습니다. 나는 이것을 Safari와 Chrome에서 테스트했으며 작동합니다.

건배.


이것은 모든 사람에게 작동하지 않을 수도 있지만 API와 다른 호스트에서 React App을 제공하고 있었고 궁극적으로 효과가 있었던 해결책은 DNS를 사용하는 것이었기 때문에이 문제를 발견했습니다.

우리의 클라이언트는 www.company-name.com에서 제공되었고 API는 company-name.herokuapp.com에있었습니다. CNAME 레코드 api.company-name.com-> company-name.herokuapp.com 을 만들고 클라이언트가 API 호출에 해당 하위 도메인을 사용하도록함으로써 Safari는이를 "타사"쿠키로 간주하는 것을 중단했습니다.

The upside is that there's very little code involved, and it's all using well-established stuff... The downside is that you need some control/ownership over the API host if you're going to use https - they need a certificate that's valid for the client domain, or users will get a certificate warning - so this wouldn't work (at least not for something end-user-facing) if the API in question isn't yours or a partner's.


Perhaps pragmatically create and click a link with an href="A.com/setCookie?cache=1231213123" and a target attribute pointing to a hidden iframe. That may bypass Safari's policy of user navigation for setting cookies (I don't have Safari handy to test.)


I did some extensive investigation around this when I was trying to deploy a site that used Windows Live ID, which depended on the ability to be able to set 3rd party cookies in order to log out. It just... didn't work. Nothing we could do would get it to work. The Live ID team also did extensive investigation and their answer was "can't make it work".


Note this line:

script.src = "A.com/setCookie?cache=1231213123";

I could not get this working until I added the http, i.e.

script.src = "http://A.com/setCookie?cache=1231213123";

I found a simple solution. You just need for first time setting cookie to check if request come from the same origin or not, if not as usual you need to return into iframe a script that will repeat this request, already having permission to assign cookie. After that you can do other request directly through iframe accessing this cookie. This helped me in my tracking system. Try, this works well.


Its worth noting that this restriction in Safari doesn't apply across subdomains. So if you directly visit sitea.com, then you can set cookies from subdomain.sitea.com without direct user interaction (iframe/JavaScript).

This was relevant for my case when developing an API. If you're visitors are arriving at mysite.com, and then you want some JavaScript to interact with your API, then if the API is hosted at api.mysite.com, then it will work on Safari.


Place this JavaScript on the page making cross-domain requests, http://example1.com/index.html:

  <script>
  var gup = function(name, url) {
     if(!url) url = location.href;
     name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
     var regexS = "[\\?&]"+name+"=([^&#]*)";
     var regex = new RegExp( regexS );
     var results = regex.exec( url );
     return results == null ? null : results[1];
  }
  var isSafari = navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && !navigator.userAgent.match('CriOS');
  var n = gup("activated");
  if(isSafari && n == null) {
     //browser is Safari and cookies have not yet been activated
     var current_url = location.protocol + '//' + location.host + location.pathname;
     var query_string = '?callback=' + encodeURIComponent(current_url + '?activated=1');
     var new_url = 'http://example2.com/activate.php' + query_string;
     window.location.href = new_url;
  }
  //the rest of your code goes here, and you can now set cross-domain cookies on Safari
  </script>

Then create a file on the other server, which needs to set cookies, http://example2.com/activate.php:

  <?php
  if(isset($_GET['callback'])) {
     header('Location: '.$_GET['callback']);
     exit();
  } else {
     //in case callback param is not set, simply go back to previous page
     echo "<script>";
     echo "window.history.back();";
     echo "</script>";
     exit();
  }
  ?>

Here's how this works:

  1. When http://example1.com/index.html is first visited, a check is made to see whether the browser is Safari and whether a GET parameter of the name "activated" does not exist. If both conditions are met (which will happen on the first visit for a Safari browser), then the browser is redirected to http://example2.com/activate.php with a GET parameter, "callback", containing the calling URL appended with an "activated" parameter.

  2. http://example2.com/activate.php simply redirects back to the URL contained in the GET parameter, "callback".

  3. When http://example1.index.html is now hit this second time after being redirected-to, the GET parameter, "activated" will now be set, so the conditional from step 1 will not execute, thus allowing the script to continue execution.

This fulfills Safari's requirement of having the browser visit the 3rd party domain at least once in order to start setting cookies.


Try something like:

var w = window.open("A.com/setCookie?cache=1231213123");
w.close();

It may bypass safari's security policy.


It isn't the missing type-attribute thats annoying you ?-)

<script type="text/javascript">
  var head = document.getElementsByTagName("head")[0];
  var script = document.createElement("script");
  script.setAttribute("type","text/javascript");
  script.src = "A.com/setCookie?cache=1231213123";
  head.appendChild(script);
</script>

참고URL : https://stackoverflow.com/questions/408582/setting-cross-domain-cookies-in-safari

반응형