50

Cookie に関して、ブラウザー間でいくつかの実際の不一致があることに気付きました。

これはかなり長くなりますので、我慢してください。

注: "testdomain.com" という名前のホスト ファイルにドメインをセットアップしました。このバグは、 "localhost" を使用している場合には機能しません。

注 2:名前で Cookie を取得するときに、Cookie のコレクションが返される場合、これが Apache/PHP でどのように機能するかを知りたいです。

ウィキペディア

ウィキペディアは次のように述べています: http://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Path

ドメインとパス
Cookie のドメインとパスは、Cookie の範囲を定義します。指定されたドメインとパスのサーバーにのみ Cookie を送り返す必要があることをブラウザに伝えます。指定しない場合、要求されたオブジェクトのドメインとパスがデフォルトになります。

押し下げると、次のようになります。

Response.Cookies.Add(new HttpCookie("Banana", "2")
{

});

要求されたオブジェクトからのドメインとして使用されるドメインを持つ Cookie を取得する必要があります。この場合は「testdomain.com」である必要があります。

W3

W3 は Cookie の仕様で次のように述べています: http://www.w3.org/Protocols/rfc2109/rfc2109

ドメイン=ドメイン

オプション。Domain 属性は、Cookie が有効なドメインを指定します。 明示的に指定されたドメインは、常にドットで始まる必要があります。

押し下げると、次のようになります。

Response.Cookies.Add(new HttpCookie("Banana", "1")
{
    Domain = Request.Url.Host
});

ホスト名を明示的にプッシュ ダウンしました。Cookie に設定されたドメイン名を取得する必要があり、ドットのプレフィックスが付けられます。この場合は「.testdomain.com」である必要があります。

また、ウィキペディアにあるものについても述べています。

ドメイン デフォルトは request-host です。(request-host の先頭にドットがないことに注意してください。)


ここまで私と?

ドメインを定義する最初の方法を使用する場合:

Response.Cookies.Add(new HttpCookie("Banana", "1")
{
    Domain = Request.Url.Host
});

結果は次のとおりです。

IE9: 1 クッキー

1 つの Cookie とドメインが明示的に設定された IE

オペラ: 1 クッキー

1 つの Cookie とドメインが明示的に設定された Opera

Firefox: 1 クッキー

1 つの Cookie とドメインが明示的に設定された Firefox

クロム: 1 クッキー

1 つの Cookie とドメインが明示的に設定された Chrome

ご覧のとおり、Opera と IE の両方が、ドット プレフィックスのない EXPLICIT ドメインを設定しています。

Firefox と Chrome DO はどちらも、ドット プレフィックスを使用して EXPLICIT ドメインを設定します。

次のコードを使用する場合:

Response.Cookies.Add(new HttpCookie("Banana", "2")
{

});

IE / Opera: どちらもまったく同じ結果になり、ドット プレフィックスのないドメインになります。

おかしなことに、Firefox と Chrome は両方ともドット プレフィックスなしで Cookie を作成します。

(すべての Cookie をクリアして、コードを再度実行しました)

ファイアフォックス:

1 つの Cookie とドメインが明示的に設定された Firefox

クロム:

1 つの Cookie とドメインが明示的に設定された Chrome

興味深いビット

ここが興味深いところです。次のようにクッキーを次々と書くと:

Response.Cookies.Add(new HttpCookie("Banana", "1")
{
    Domain = Request.Url.Host
});
Response.Cookies.Add(new HttpCookie("Banana", "2")
{

});

個人的には、ブラウザに 1 つの Cookie が存在することを期待します。これは、Cookie 名に基づいていると想定しているためです。

ここに私が観察したものがあります:

IE/Opera では、LAST Cookie セットが使用される Cookie です。これは、Cookie 名とドメイン名が同一であるためです。

ドメイン名を明示的にドットで定義すると、両方のブラウザで同じ名前の最後の Cookie である 1 つの Cookie が表示されます。

一方、Chrome と Firefox では、複数の Cookie が表示されます。

値をページにダンプするために、次の JavaScript を作成しました。

<script type="text/javascript">

(function () {
    var cookies = document.cookie.split(';');
    var output = "";

    for (var i = 0; i < cookies.length; i++) {
        output += "<li>Name " + cookies[i].split('=')[0];
        output += " - Value " + cookies[i].split('=')[1] + "</li>";
    }

    document.write("<ul>" + output + "</ul>");
})();

</script>

結果は次のとおりです。

IE - 2 つの Cookie セット (ブラウザには 1 が表示されます):

IE - 2 つの Cookie セット、結果

Opera - 2 つの Cookie セット (ブラウザには 1 が表示されます):

ここに画像の説明を入力

Firefox - 2 つの Cookie が設定され、ブラウザには 2 つが表示されます!:

ここに画像の説明を入力

Chrome - 2 つの Cookie が設定され、ブラウザには 2 つが表示されます!:

ここに画像の説明を入力


今、あなたはおそらくこれがすべてだと思っているでしょう。

良い:

  1. C# で名前で Cookie にアクセスすると、1 つの Cookie が返されます。(その名前を持つ最初の Cookie)
  2. ブラウザはすべての Cookie をサーバーに送信します
  3. ブラウザは、Cookie のキーと値以外の情報を送信しません。(これは、サーバーがドメインを気にしないことを意味します)
  4. インデックスで取得すると、同じ名前の両方の Cookie にアクセスできます

問題...

Cookie をプッシュしたときに、Cookie でドメインを指定するように認証を変更する必要がありました。

これにより Chrome と Firefox が壊れ、サーバーが古い認証 Cookie を認証しようとするため、ユーザーはログインできなくなりました。これは、(私の理解では) 認証 Cookie 名を使用して Cookie を取得するためです。

2 つの Cookie があっても、最初の 1 つが取得され、たまたま古いものであり、認証が失敗し、ユーザーがログインしていません。正しい Cookie がリストの最初にあり、認証が成功することもあります...

最初に、古いドメインで Cookie をプッシュして期限切れにすることで、これを解決しました。これは Chrome と Firefox で機能しました。

しかし、両方のブラウザーがドメインを気にせず、名前に基づいて Cookie のみを比較するため、IE/Opera が壊れてしまいました。

私の結論は、Cookie のドメインは完全に時間の無駄だということです。

ドメインを指定する必要があり、ユーザーがブラウザのキャッシュをクリアすることに頼ることはできないと仮定します。どうすればこの問題を解決できますか?

アップデート:

.NET がユーザーをサインアウトする方法を掘り下げます。

if (FormsAuthentication._CookieDomain != null)
{
    httpCookie.Domain = FormsAuthentication._CookieDomain;
}

フォーム認証が期限切れの Auth Cookie をプッシュすることは完全に可能であるように見えますが、これはユーザーが認証される Cookie とはまったく関係ありません。現在の認証 Cookie のドメインは使用しません。

ドメインは Cookie を使用してサーバーにプッシュバックされないため、とにかく使用できません。

更新 2

FormsAuthentication が本当に壊れているようです。ユーザーを認証するときに Cookie で明示的なドメイン名を使用し、セッションがタイムアウトするのを待ってからページを更新すると、FormsAuthentication で使用される Cookie を生成する方法によってドメインが null になり、ブラウザがドットレスドメイン。

フォームを Cookie に割り当てるには、事前にフォームにドメインを割り当てる必要があります。これにより、マルチテナント システムが壊れます...

4

2 に答える 2

10

@WilliamBZAの提案は最初の問題を解決するのに役立ちましたが、サインアウト/セッションタイムアウトのバグにより、Cookieが暗黙のドメインCookieを作成する結果になり、解決策は...

.NET で明示的な Cookie を使用しないでください。

あまりにも多くの問題がありますが、フォーム/ドメイン、Cookie/ドメインなどを明示することで確実に解決できます。正しいドメインがどこでも使用されるようにするためです。しかし、アプリケーションが複数のドメインをホストしていたり​​、マルチ テナントであったりすると、問題が大きくなります。

教訓は学んだ。明示的な Cookie を使用しないでください。

于 2012-06-01T08:36:39.317 に答える
5

Cookie の扱いが異なる理由はわかりませんが、Cookie のドメインを使用するのではなく、サブアプリケーションごとに異なる Cookie 名を使用することで簡単に修正できます。

フォーム認証の場合、ASPXAUTH Cookie の名前を変更します。

于 2012-05-26T08:03:00.697 に答える