クッキーに関するいくつかの基本的なことを見逃しているに違いありません。 localhostで、サーバー側でCookieを設定するときandlocalhost(または.localhost)としてドメインを明示的に指定します。一部のブラウザではCookieが受け入れられないようです。
Firefox 3.5: FirebugでHTTPリクエストをチェックしました。私が見るものは:
Set-Cookie:
name=value;
domain=localhost;
expires=Thu, 16-Jul-2009 21:25:05 GMT;
path=/
または(ドメインを.localhostに設定した場合):
Set-Cookie:
name=value;
domain=.localhost;
expires=Thu, 16-Jul-2009 21:25:05 GMT;
path=/
いずれの場合も、Cookieは保存されません。
IE8:追加のツールは使用しませんでしたが、後続のリクエストでCookieが返送されないため、Cookieも保存されていないようです。
Opera 9.64: localhostと.localhostの両方workが、PreferencesでCookieのリストを確認すると、ドメインが設定されますlocalhost.local(リストグループ内)の下にリストされている場合でも、localhost.localに。
Safari 4: localhostと.localhostの両方workが、Preferencesでは常に.localhostとしてリストされます。一方、明示的なドメインのないCookieは、localhostのみ(ドットなし)として表示されます。
ローカルホストの問題は何ですか?このような多くの矛盾のため、localhostに関連するいくつかの特別なルールが必要です。また、ドメインの前にドットを付ける必要がある理由は完全にはわかりません。 RFC 2109は明示的に次のように述べています:
Domain属性の値に埋め込みドットが含まれていないか、ドットで始まっていません。
どうして?この文書は、セキュリティに関して何かしなければならないことを示しています。仕様全体を読んだわけではないことを認めなければなりません(後で読むかもしれません)が、少し奇妙に聞こえます。これに基づいて、localhostでCookieを設定することは不可能です。
設計上、ドメイン名には少なくとも2つのドットが必要です。そうでない場合、ブラウザはそれらを無効とみなします。 ( http://curl.haxx.se/rfc/cookie_spec.html のリファレンスを参照)
localhost
で作業する場合、Cookieドメインを完全に省略する必要があります。 ""
の代わりに"localhost"
またはNULL
またはFALSE
に設定するだけでは十分ではありません。
PHPについては、 http://php.net/manual/en/function.setcookie.php#73107 のコメントを参照してください。
JavaサーブレットAPIを使用する場合は、cookie.setDomain("...")
メソッドをまったく呼び出さないでください。
私は@Ralph Buchfelderに広く同意しますが、ローカルマシン上でいくつかのサブドメイン(example.com、fr.example.com、de.example.comなど)でシステムを複製しようとするときの実験によって、これをいくらか増幅します( OS X/Apache/Chrome | Firefox)。
/ etc/hostsを編集して、いくつかの架空のサブドメインが127.0.0.1を指すようにしました。
127.0.0.1 localexample.com
127.0.0.1 fr.localexample.com
127.0.0.1 de.localexample.com
Fr.localexample.comで作業しており、domainパラメーターを省略した場合、cookieはfr.localexample.comに対して正しく保存されますが、他のサブドメインでは表示されません。
「.localexample.com」のドメインを使用すると、fr.localexample.comのCookieが正しく保存され、他のサブドメインでisが表示されます。
「localexample.com」のドメインを使用する場合、または「localexample」または「localhost」のみのドメインを試行した場合、Cookieは保存されませんでした。
「fr.localexample.com」または「.fr.localexample.com」のドメインを使用すると、cookieはfr.localexample.comに対して正しく保存され、他のサブドメインでは(正しく)見えなくなります。
そのため、ドメイン内に少なくとも2つのドットが必要であるという要件は、なぜ必要なのかわかりませんが、正しいように見えます。
誰もがこれを試してみたい場合、ここにいくつかの便利なコードがあります:
<html>
<head>
<title>
Testing cookies
</title>
</head>
<body>
<?php
header('HTTP/1.0 200');
$domain = 'fr.localexample.com'; // Change this to the domain you want to test.
if (!empty($_GET['v'])) {
$val = $_GET['v'];
print "Setting cookie to $val<br/>";
setcookie("mycookie", $val, time() + 48 * 3600, '/', $domain);
}
print "<pre>";
print "Cookie:<br/>";
var_dump($_COOKIE);
print "Server:<br/>";
var_dump($_SERVER);
print "</pre>";
?>
</body>
</html>
localhost:以下を使用できます:domain: ".app.localhost"
これは動作します。 Cookieを設定するには、ドメイン名に'domain'パラメーターに1つ以上のドットが必要ですが必要です。その後、api.app.localhost:3000
などのローカルホストサブドメイン間でセッションを動作させることができます。
次のように「localhost」の明示的なドメインでCookieが設定されている場合...
Set-Cookie:name = value; domain = localhost; expires = Thu、2009年7月16日21:25:05 GMT; path = /
...その後、ブラウザはそれを無視します 少なくとも2つのピリオドを含まず、7つの特別に処理されるトップレベルドメインの1つではない 。
...ドメインには、「。com」、「。edu」、「va.us」という形式のドメインを防ぐために、少なくとも2つまたは3つのピリオドが必要です。以下にリストされている7つの特別なトップレベルドメインのいずれかで障害が発生したドメインは、2つの期間のみを必要とします。他のドメインには少なくとも3つ必要です。 7つの特別なトップレベルドメインは、「COM」、「EDU」、「NET」、「ORG」、「GOV」、「MIL」、および「INT」です。
上記の期間の数は、おそらく先行期間が必要であると想定していることに注意してください。ただし、この期間は 現代のブラウザでは無視されます であり、おそらく読まれるべきです...
少なくとも1(1)または2(2)期間
ドメイン属性のデフォルト値は Cookie応答を生成したサーバーのホスト名 であることに注意してください。
したがって、localhostに設定されていないCookieの回避策は、単にドメイン属性を指定せず、ブラウザにデフォルト値を使用させることです-これは表示されませんドメイン属性の明示的な値と同じ制約があります。
結果はブラウザによって異なりました。
Chrome-127.0.0.1は機能しましたが、localhost .localhostと ""は機能しませんでした。 Firefox- .localhostは機能しましたが、localhost、127.0.0.1、および ""は機能しませんでした。
Opera、IE、またはSafariでテストしていない
この問題を自分でトラブルシューティングするのに多大な時間を費やしました。
PHPを使用すると、このページには何も機能しませんでした。最終的に、コードで PHPのsession_set_cookie_params() の「secure」パラメーターが常にTRUEに設定されていることに気付きました。
Httpsでlocalhostにアクセスしていなかったので、ブラウザはcookieを受け入れません。そこで、コードのその部分を変更して、$ _ SERVER ['HTTP_Host']が「localhost」であるかどうかに基づいて「secure」パラメーターを条件付きで設定しました。うまく機能しています。
これが誰かの助けになることを願っています。
提案された修正はどれも私にとってはうまくいきませんでした-null、falseに設定、2つのドットを追加するなど-うまくいきませんでした。
最後に、localhostである場合はCookieからドメインを削除しましたが、今ではChrome 38で機能します。
前のコード(機能しませんでした):
document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';domain=.' + document.domain + ';path=/;';
新しいコード(現在動作中):
if(document.domain === 'localhost') {
document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';path=/;' ;
} else {
document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';domain=.' + document.domain + ';path=/;';
}
あなたはlocalhost.org
またはむしろ.localhost.org
を使用することができ、それは常に127.0.0.1
に解決されます
ドメインとして127.0.0.1を使用してローカルでテストする方がはるかに幸運でした。理由はわかりませんが、localhostや.localhostなどと結果が混在していました。
https://<local-domain>
を使用してからhttp://<local-domain>
を使用すると問題が発生するようです。 http://
サイトは、https://
サイトがそれらを設定した後、リクエストを含むCookieを送信しません。強制的にリロードしてキャッシュをクリアしても効果はありません。 Cookieの手動クリアのみが機能します。また、https://
ページでそれらをクリアすると、http://
ページが再び機能し始めます。
「厳格なセキュアCookie」に関連しているようです。良い説明 ここ 。 2017年4月19日に Chrome 58でリリース でした。
Chromeは実際にセキュアCookieと非セキュアCookieの両方を記録するように見えます。アドレスバーアイコンをクリックすると、ページのプロトコルに応じて正しいCookieが表示されるためです。
ただし、同じドメインに同じ名前のセキュアCookieがある場合、Developer tools > Application > Cookies
は非セキュアCookieを表示しません。また、非セキュアCookieをリクエストとともに送信しません。これはChromeバグのように見えますが、この動作が予想される場合は、http
ページでセキュアCookieを表示し、それらがオーバーライドされていることを示す方法が必要です。
回避策は、httpサイト用かhttpsサイト用かによって異なる名前のcookieを使用し、アプリに固有の名前を付けることです。 __Secure-
プレフィックスは、Cookieが厳密に安全である必要があることを示します。また、安全なものと安全でないものは衝突しないため、良い習慣でもあります。プレフィックスにも その他の利点 があります。
Httpsアクセスとhttpアクセスで異なる/etc/hosts
ドメインを使用しても機能しますが、誤ってhttps://localhost
にアクセスすると、同じ名前のCookieがhttp://localhost
サイトで機能しなくなるため、これは適切な回避策ではありません。
Chromeバグレポート を提出しました。
同じ問題があり、ドメインを指定せずにCookie名自体に2つのドットを挿入することで修正しました。
set-cookie: name.s1.s2=value; path=/; expires=Sun, 12 Aug 2018 14:28:43 GMT; HttpOnly
私は少し遊んでいた。
Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=localhost; Path=/
firefoxおよびChromeで動作します。しかし、私はそれをcurlで動作させる方法を見つけませんでした。 Host-Headerを試してみましたが、解決できました。
ただし、カールに設定すると、カールで動作します
Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=127.0.0.1; Path=/
代わりに。 (Firefoxでは動作しません。)
document.cookie = valuename + "=" + value + ";" +有効期限+ "; domain =; path = /";
この「domain =; path = /」; Cookieはサブドメインで機能するため、動的ドメインを使用します。ローカルホストでテストしたい場合は動作します
2011年以来オープンしているChromiumの問題 があります。ドメインを明示的に「localhost」に設定する場合は、false
またはundefined
として設定する必要があります。
別の重要な詳細、expires =は、次の日時形式を使用する必要があります:Wdy、DD-Mon-YYYY HH:MM :SS GMT( RFC6265-セクション4.1.1 )。
Set-Cookie:
name=value;
domain=localhost;
expires=Thu, 16-07-2019 21:25:05 GMT;
path=/
別のドメインからCookieを設定している場合(つまり、XHRクロスオリジンリクエストを作成してCookieを設定している場合)、Cookieを取得するために使用するXMLHttpRequestでwithCredentials
属性をtrueに設定していることを確認する必要があります- ここ
ここでの答えはどれもうまくいきませんでした。 PHPをページの一番最初に置くことで修正しました。
他のヘッダーと同様、Cookieはスクリプトからの出力の前に送信する必要があります(これはプロトコルの制限です)。これには、タグや空白を含む出力の前に、この関数を呼び出す必要があります。