SafariでクロスドメインCookieを設定する
-
03-07-2019 - |
質問
Evernote のブックマークレットはこれを行うことができるため、最も賛成の回答はこれに答えません報奨金は(非生産的な方法で)そこに行きます。
ドメインA.com(Cookieにhttpを設定)をドメインB.comから呼び出す必要があります。 ドメインB.comで行うことはすべて(javascript)です:
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = "A.com/setCookie?cache=1231213123";
head.appendChild(script);
これにより、Safariを除く、テストしたすべてのブラウザーのA.comにCookieが設定されます。 驚くべきことに、これはP3PヘッダーがなくてもIE6で機能します。
Safariでこの機能を使用する方法はありますか?
解決
Safariには、ユーザーが選択したページ(<!> quot; navigated to <!> quot;)のみにCookie書き込みを制限する保守的なCookieポリシーが付属しています。このデフォルトの保守的なポリシーは、Cookieを書き込もうとして失敗するフレームベースのサイトを混乱させる可能性があります。
これを回避する方法が見つかりませんでした。
価値がある場合、<script
<!> gt;を使用しても、ChromeはCookieを設定しません。メソッドを追加しますが、非表示の<img
<!> gtがある場合同じソースで、Chromeは他のブラウザに加えて動作します(Safariを除く)
他のヒント
これが有効なソリューションです:
http://anantgarg.com/2010/02 / 18 / cross-domain-cookies-in-safari /
作業方法2014-2016:
ドメインに対してwindow.openを実行する/ Cookieを割り当てる/ポップアップを閉じる必要があります。ドメインはセーフリストに登録されています。
フラッシュがインストールされていると仮定すると、ちょっとした悪意があります。
まだ動作するかどうかはわかりませんが、Flashの<!> quot;ローカル共有オブジェクト<!> quot;別名 Flash Cookie は、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年にこの作業を行うための適切な回避策があります。たとえば、iframeをサイトx.comに含むウェブサイトy.comがあるとします。 x.com iframeはCookieを保存したいと考えています。 Safariポリシーでは許可されていませんが、y.comはそれを保存できます。そのため、y.comはx.comからのメッセージをリッスンしてから、Cookie自体を保存する必要があります。
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がCookieを保存する必要がある場合、y.comにメッセージを投稿する必要があります:
window.parent.postMessage('cookieset|'+ckName+'|'+ckVal+'|'+days,'*');
また、Cookieを読み取る場合は、iframeにメッセージを投稿する方法を使用できます。または、javascriptを使用してx.com iframe urlのパラメーターとして含めることができます:
iframe.setAttribute('url','x.com/?cookieval='+YOUR_COOKIE_GET_METHOD('cookiename'));
仕事で思いついた回避策は、window.open()を介してCookieを設定することでした-最適ではないかもしれません((いポップアップウィンドウが開いているため)私たちにとっても。とにかく、OAuth認証のためにポップアップウィンドウを開く必要がありました。
だから私たちがやったことの要点は:
- ユーザーがB.comのリンクをクリックします
- A.com/setCookieへのポップアップウィンドウが開きます
- A.comはCookieを設定し、適切な場所でB.comにリダイレクトします
また、すべてのソリューションで有効ではありませんが、私たちのソリューションでは機能しました。これがお役に立てば幸いです。
この質問はかなり古いことは知っていますが、これはクッキーの問題を解決するのに役立ちました:
var cookieForm = document.createElement("form");
cookieForm.action = "A.com/setCookie?cache=1231213123";
cookieForm.method = "post";
document.body.appendChild(cookieForm);
cookieForm.submit();
Cookieを設定するページにフォームを投稿するというアイデア。
* 編集 * この回避策は、WebKitでクローズされたと報告されています。
ルカ、
わかりました。したがって、この答えは2年ですが、...非表示のiframeにフォームを投稿すると、iframeからcookieを設定できます。これを行うには、フォームを作成します。
<form id="myiframe" action="http://yourdomain.com" method="POST" target="iframe_target">
次に、JavaScriptでフォームへの参照を取得し、submitを呼び出します:
document.getElementsByTagName('form')[0].submit();
iframeのオンロードをリッスンするか、iframeアクションページでロードを通知するjavascriptを発行することができます。 SafariとChromeでこれをテストしましたが、動作します。
乾杯。
これはすべての人に有効ではないかもしれませんが、APIとは異なるホストからReactアプリを提供していたため、この問題に出くわし、最終的に有効なソリューションはDNSを使用することでした:
クライアントはwww.company-name.comから提供され、APIはcompany-name.herokuapp.comにありました。 CNAME レコードを作成するapi.company-name.com-<!> gt; company-name.herokuapp.comで、クライアントにそのサブドメインをAPI呼び出しに使用させると、Safariはそれを<!> quot; third
長所は、コードがほとんど含まれないことであり、すべてが十分に確立されたものを使用しています...短所は、httpsを使用する場合、APIホストに対する制御/所有権が必要なことです。クライアントドメインに対して有効な証明書、またはユーザーに証明書の警告が表示されます-したがって、問題のAPIが自分のものでもパートナーのものでもない場合、これは機能しません(少なくともエンドユーザー向けのものでは機能しません)。
おそらく、非表示のiframeを指すhref="A.com/setCookie?cache=1231213123"
およびターゲット属性を持つリンクを実用的に作成してクリックします。これは、Cookieを設定するためのユーザーナビゲーションのSafariのポリシーをバイパスする可能性があります(テストするのに便利なSafariはありません。)
Windows Live IDを使用するサイトを展開しようとしていたときに、これについていくつかの広範な調査を行いました。ただ…うまくいきませんでした。できることは何もありません。 Live IDチームも大規模な調査を行い、その答えは<!> quot;それを機能させることができません<!> quot;。
でした。この行に注意してください:
script.src = "A.com/setCookie?cache=1231213123";
httpを追加するまでこれを機能させることができませんでした。つまり、
script.src = "http://A.com/setCookie?cache=1231213123";
簡単な解決策を見つけました。リクエストの送信元が同じかどうかを確認するために初めてcookieを設定する必要があります。通常ではない場合は、このリクエストを繰り返すスクリプトをiframeに戻す必要があります。その後、このCookieにアクセスするiframeから直接他のリクエストを行うことができます。これは私の追跡システムに役立ちました。試してください、これはうまく機能します。
Safariのこの制限はサブドメインには適用されないことに注意してください。したがって、sitea.comに直接アクセスすると、直接的なユーザー操作(iframe / JavaScript)なしでsubdomain.sitea.comからCookieを設定できます。
これは、APIを開発する際の私の事例に関連していました。訪問者がmysite.comにアクセスしていて、JavaScriptでAPIとやり取りしたい場合、APIがapi.mysite.comでホストされている場合、Safariで動作します。
このJavaScriptをクロスドメインリクエストを行うページに配置します。 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>
次に、Cookieを設定する必要がある他のサーバー上にファイルを作成します。 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();
}
?>
この仕組みは次のとおりです。
-
http://example1.com/index.html に初めてアクセスすると、ブラウザがSafariであるかどうか、および名前<!> quot; activated <!> quotのGETパラメータがあるかどうかを確認します。存在しない。両方の条件が満たされている場合(Safariブラウザーの最初のアクセス時に発生します)、ブラウザーは httpにリダイレクトされますGETパラメータ<!> quot; callback <!> quot;を含む://example2.com/activate.php には、<!> quot; activated <!> quotが追加された呼び出しURLが含まれます。パラメータ。
-
http://example2.com/activate.php は、単にGETパラメーター<!> quot; callback <!> quot;に含まれるURL。
-
http://example1.index.html が2回目にヒットしたときリダイレクト先、GETパラメーター、<!> quot; activated <!> quot;これで設定されるため、ステップ1の条件は実行されないため、スクリプトの実行を継続できます。
これは、Cookieの設定を開始するために、ブラウザが少なくとも1回はサードパーティドメインにアクセスするというSafariの要件を満たします。
次のようなものを試してください:
var w = window.open("A.com/setCookie?cache=1231213123");
w.close();
サファリのセキュリティポリシーをバイパスする可能性があります。
迷惑なのはタイプ属性の欠落ではないのですか?-)
<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>