web-dev-qa-db-ja.com

クッキーのサーバー側を削除する正しい方法

私の認証プロセスでは、ユーザーがログインするときに一意のトークンを作成し、それを認証に使用されるCookieに入れます。

したがって、サーバーから次のようなものを送信します。

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/;

これはすべてのブラウザで動作します。その後、Cookieを削除するために、1970年1月1日にexpiresフィールドが設定された同様のCookieを送信します

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/; expires=Thu, Jan 01 1970 00:00:00 UTC; 

また、Firefoxでは正常に機能しますが、IEまたはSafariのCookieは削除されません。

それでは、Cookieを削除する最良の方法は何ですか(できればJavaScriptなしで)? set-the-expires-in-the-pastメソッドはかさばっているようです。また、なぜこれはFFでは機能するがIEまたはSafariでは機能しないのですか?

115
Joshkunz

同じCookie値に; expiresを追加して送信しても、Cookieは破棄されません。

空の値を設定してCookieを無効にし、expiresフィールドも含めます。

Set-Cookie: token=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT

すべてのブラウザにCookieを強制的に削除させることはできないことに注意してください。クライアントは、Cookieの有効期限が切れた場合でも、Cookieが保持されるようにブラウザーを構成できます。上記のように値を設定すると、この問題が解決します。

189
Lekensteyn

「期限切れ」を過去の日付に設定することは、Cookieを削除する標準的な方法です。

あなたの問題は、おそらく日付形式が従来のものではないためです。 IEはおそらくGMTのみを想定しています。

12
irreputable

この回答を書いている時点で、 この質問に対する受け入れられた回答 は、Expires値が過去にある置換Cookieを受け取ったときに、ブラウザーがCookieを削除する必要がないことを示しているようです。その主張は誤りです。 Expiresを過去に設定することは、Cookieを削除する標準の仕様準拠の方法であり、ユーザーエージェントはそれを尊重するために仕様で要求されます。

過去にExpires属性を使用してCookieを削除することは正しいことであり、仕様で規定されているCookieを削除する方法です。 RFC 6255 の例のセクションには次のように記載されています。

最後に、Cookieを削除するために、サーバーは有効期限が過去のSet-Cookieヘッダーを返します。サーバーは、Set-CookieヘッダーのPath属性とDomain属性がCookieの作成時に使用された値と一致する場合にのみ、Cookieの削除に成功します。

ユーザーエージェントの要件セクションには次の要件が含まれています。これらの要件は、ユーザーエージェントが有効期限が過去の同じ名前

  1. [新しいCookieを受け取ったときに] Cookieストアに、新しく作成されたCookieと同じ名前、ドメイン、およびパスを持つCookieが含まれている場合:

    1. ...
    2. ...
    3. 新しく作成されたCookieの作成時間を更新して、古いCookieの作成時間と一致させます。
    4. Cookieストアから古いCookieを削除します。
  2. 新しく作成したCookieをCookieストアに挿入します。

Cookieの有効期限が過去にある場合、Cookieは「期限切れ」になります。

ユーザーエージェントは、期限切れのCookieがいつでもCookieストアに存在する場合、Cookieストアからすべての期限切れのCookieを排除する必要があります。

上記のポイント11-3、11-4、および12は、同じ名前、ドメイン、およびパスの新しいCookieを受信した場合、古いCookieを消去して新しいCookieに置き換える必要があることを意味します。最後に、期限切れのCookieに関する以下のポイントは、それが行われた後、newCookieもalsoすぐに削除する必要があることを示しています。この点については、この仕様ではブラウザーにゆらぎの余地はありません。ブラウザーがCookieの有効期限を無効にするオプションをユーザーに提供した場合、受け入れられた答えが一部のブラウザーが行うことを示唆しているため、仕様に違反しています。 (そのような機能はほとんど使い道がありませんが、私が知る限り、どのブラウザにも存在しません。)

では、なぜこの質問のOPはこのアプローチが失敗するのを観察したのですか? Internet Explorerの動作を確認するためにInternet Explorerのコピーを消したことはありませんが、OPのExpires値の形式が間違っていたためと思われます。彼らはこの値を使用しました:

expires=Thu, Jan 01 1970 00:00:00 UTC;

ただし、これは2つの点で構文的に無効です。

仕様の 構文セクション は、Expires属性の値が

rfc112 -date、 [RFC2616]、セクション3.3.1 で定義

上記の2番目のリンクをたどると、これは形式の例として示されています。

Sun, 06 Nov 1994 08:49:37 GMT

そして構文定義を見つけます...

  1. 質問者が使用するmonth day year形式ではなく、day month year形式で日付を記述する必要があります。

    具体的には、次のようにrfc1123-dateを定義します。

    rfc1123-date = wkday "," SP date1 SP time SP "GMT"
    

    そしてdate1を次のように定義します:

    date1        = 2DIGIT SP month SP 4DIGIT
                 ; day month year (e.g., 02 Jun 1982)
    

そして

  1. タイムゾーンとしてUTCを許可していません。

    仕様には、この形式で許容されるタイムゾーンオフセットに関する次のステートメントが含まれています。

    すべてのHTTP日付/時刻スタンプは、例外なくグリニッジ標準時(GMT)で表現する必要があります。

    さらに、この日付/時刻形式の元の仕様をさらに掘り下げると、最初の仕様で https://tools.ietf.org/html/rfc822構文section は、可能な値として「UT」(「世界時」を意味する)をリストしますが、UTC(協定世界時)ではないnotを有効としてリストします。私の知る限り、この日付形式で「UTC」を使用することはneverが有効でした。 1982年にフォーマットが最初に指定されたときは有効な値ではなく、HTTP仕様では、すべての「ゾーン」の使用を禁止することにより、厳密にmore 「「GMT」以外の値。

ここで質問者が代わりにthisのようなExpires属性を使用していた場合:

expires=Thu, 01 Jan 1970 00:00:00 GMT;

それはおそらく働いていたでしょう。

10
Mark Amery