クッキー設定子

Set-Cookie: 欄 (HTTP)

[3] HTTPSet-Cookie: 応答頭欄は、 クライアントに対して Cookie を設定することを指示します。

[322] Set-Cookie: 頭欄Netscape 社によってはじめに定義・実装され、 後にWebブラウザーを含む数多くの HTTP 利用者エージェントで実装されるに至りました。 なお、 Set-Cookie (>>311) やその改訂版 Set-Cookie2 (>>308) は IETF によって RFC 2109, RFC 2965 として標準化されましたが、 Netscape の定義と互換性がないため無視され、事実上死文化しています。

仕様書

構文

[4] Set-Cookie: 欄の欄本体

Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
のように名前と値の組 (属性 (attribute) ) の連続として記述します >>2

[378] Set-Cookie: 欄の構文は次のように定義されています。 起源鯖はこの構文に従うべきです >>377

[379] なぜか違反を完全に禁止はされていません...
[380] RFC 6265 による Set-Cookie: 欄の構文
 set-cookie-header = "Set-Cookie:" SP set-cookie-string
 set-cookie-string = cookie-pair *( ";" SP cookie-av )
[381] 詳しくは Cookieの属性の項をご覧下さい。

文脈

[321] 起源鯖は、 Set-Cookie: 欄を任意のHTTP 応答に含めて構いません >>371

RFC 2109, RFC 2965Set-Cookie, Set-Cookie2 を任意の応答に含めて構わないとしていました。 >>319, >>318

[52] WebSocket handshake でも使うことができます。

複数のヘッダー

[16] 起源鯖は複数の Set-Cookie: 欄を含めて構いません >>2, >>371

[51] HTTP は値がリスト (#) でないヘッダーを複数個含めることを禁じていますが、 Set-Cookie: ヘッダーは歴史的理由により意図的違反しています >>50

[373] 起源鯖は複数の Set-Cookie: 欄を1つに折り畳みするべきではありません, は構文上、値の中に普通に使える文字なので、折り畳みによって意味が変わってしまうことがあります。 >>371

[374] なぜ完全に禁止じゃなくてべきなんでしょうね。正当な理由ってあるのでしょうか。 アプリケーション鯖HTTP が分かれていて、アプリケーションから HTTP を完全に制御できなくて、 HTTP で勝手に折り畳みしてしまう糞実装とか考慮してるんでしょうか・・・。
[14] 元々 , の使用が禁止されていたのは複数の Set-Cookie: 頭欄を連結した時に , が使われることへの配慮でしょうか、と思いきや、 Expires では ,曜日の後に使われています。 それならなんで禁止されているのでしょう。

[18] 複数の Set-Cookie: 欄で同じ名前の Cookie が設定されていた時の扱いはCookieの属性の項をご覧下さい。

[320] RFC 2109, RFC 2965 でも複数の Set-Cookie, Set-Cookie2応答1つに含まれても構わないと明記していました。 また、途中の関門 (gateway) 折り畳み (fold) され得ることにも言及されていました。 >>319, >>318

構文解析

[8] Set-Cookie: ヘッダーの値は、次のように構文解析しなければなりません >>7

  1. [6] クッキーの名前と値を次のように決定します。
    1. [9] 値に ; が含まれていれば最初の ; の直前まで、 含まれていなければ全体を対象とします。
    2. [10] = が含まれていなければ、ここで終わってこのヘッダーは無視します。
    3. [11] 最初の = の直前までを名前、直後からを値とします。 (空文字列であることもあります。)
    4. [12] 名前と値の最初と最後から WSP を除去します。
    5. [13] 名前が空文字列なら、ここで終わってこのヘッダーは無視します。
  2. [15] ヘッダーの値を処理し終わっていれば、ここで終わります。 まだ残っていれば、最初の文字は ; なので、これを読み飛ばして次の処理を行います。
    1. [23] 値に ; が含まれていれば最初の ; の直前まで、 含まれていなければ全体を対象とします。
    2. [24] = が含まれていれば最初の = の直前までを属性名、直後からを属性値とし、含まれていなければ全体を属性名、空文字列を属性値とします。
    3. [25] 属性名と属性値の最初と最後から WSP を除去します。
    4. [26] 属性名に依存する方法で処理します。
    5. >>15 に戻ります。
属性の構文解析の方法は、それぞれの項を参照してください。

[28] 構文解析の結果ヘッダーが無視されなかった場合、得られた名前、値、 属性のリストに関して要求URLからクッキーを受信 (receive a cookie) したといいます。 利用者エージェントクッキーを受信した時の操作は、 >>27 を参照してください。

[82] 構文上生成は認められていないのですが、 特に何も必要がないときにヘッダー値空文字列Set-Cookie: ヘッダー生成するサーバーがあるようです。

属性

[382] Set-Cookie: 欄の値としては、名前と値の組 (cookie-pair) と、それに続く0個以上の属性を指定することができます。詳しくは Cookieの属性の項をご覧下さい。

利用者エージェントの処理モデル

[35] 利用者エージェントは、 Set-Cookie: ヘッダーを無視して構いません >>7

[36] 例えば第三者クッキーを無視して構いません >>7

[46] 利用者エージェントは、クッキーが無効に設定されている場合、応答Set-Cookie: を処理してはなりません >>45

[27] 利用者エージェントは、クッキーを受信 (receive a cookie) したら、 次のように処理しなければなりません >>31

  1. [32] 利用者エージェントクッキーを無視してここで終わっても構いません。
  2. [33] 指定された名前と値を持つクッキーを作成します。
  3. [34] クッキーの最終アクセス時刻を現在日時に設定します。
  4. [37] Max-Age/Expires 属性Domain 属性Path 属性に関連する処理を行います (それぞれの項を参照)。
  5. [60] Secure 属性があれば、 クッキーの保安のみフラグを設定します。なければ設定しません。
  6. [61] HttpOnly 属性があれば、 クッキーのHTTPのみフラグを設定します。なければ設定しません。
  7. [62] 「非HTTP」API から受信したクッキーで、 クッキーのHTTPのみフラグが設定されているなら、クッキーを無視してここで終わります。
  8. [63] 名前、ドメイン、パスが同じクッキーが既に保存されているなら、
    1. [64] クッキー「非HTTP」APIから受信した場合で、 既存のクッキーのHTTPのみフラグが設定されているなら、 新しいクッキーを無視してここで終わります。
    2. [65] 新しいクッキーの作成時刻を既存のクッキーの値に設定します。
    3. [66] 既存のクッキーを削除します。
  9. [67] 新しいクッキーを保存します。

[47] 利用者エージェントによっては、クッキーの保存の度に利用者に承認するか確認する機能を提供していることもあります。 一度に大量の確認が表示されることもよくありますが、それでもプライバシーを気にして確認を求める利用者も存在しています。 >>45

[48] 確認と保存が同期的に実装されているとすると、レンダリングがその分遅延することになります。 非同期的に実装されているとすると、タイミングによっては発行済のクッキースクリプトが取得できませんから、 互換性の問題が生じるかもしれません。

状態符号との関係

[375] Set-Cookie:状態符号に関わらず任意の HTTP 応答で使うことができます。 利用者エージェント1xx の場合にこれを無視して構いませんが、 それ以外の場合は処理しなければなりません>>371

[305] 利用者エージェント状態符号リダイレクトであっても、 (そのリダイレクトが帰ってきた要求URL に関して) Set-Cookie: 頭欄に従った処理をするべきです。

上書き

[17] DomainPathNAME が同じ Cookie があれば、 値は上書きされて、最新のものだけが残ります。 >>2

[19] 仕様上は PathNAME とありますが、 Domain も実際には見ています。

[20] >>17 の上書き判定における Path は完全一致 >>2 なので、 例えば /foo/foo/bar で同じ名前の Cookie が設定されると、 /foo/bar では両方が有効になります。

[345] RFC 2109 では NAME が同じで PathDomain文字列として一致するなら >>343RFC 2965 では NAME が同じで Path文字列として一致Domain大文字・小文字を区別しない一致するなら上書きする >>344、 とされていました。
[349] RFC 2965 でも Port 属性はここでの一致判定には含まれないようです。
[350] RFC 2109RFC 2965 では属性の名前の大文字と小文字を区別しないことになっていますが、 ここでの扱いは明確にされていません。

[346] 新しい CookieExpires が過去であれば、 古い Cookie は削除され、新しい Cookie も蓄積されません。

[347] RFC 2109RFC 2965 では Max-Age0 であれば、あるいは RFC 2965 では Discard 属性があれば、古い Cookie は削除され、新しい Cookie も蓄積されません。 >>343, >>344

串とキャッシュの処理モデル

[22] Set-Cookie: 頭欄をそのままクライアントに渡すべきです。 状態符号200 であれ 304 であれ、です。 >>2

キャッシュ可能性

[376] Set-Cookie: 欄の有無はキャッシュ可能性に影響しません >>371, >>5

[21] NetscapeCookie 仕様では、 Set-Cookie: ヘッダーキャッシュするべきではない >>2 とされていました。
[361] RFC 2109RFC 2965 は、HTTP/1.0 に基づくSet-Cookie:Set-Cookie2: との関わりを考察しています >>359, >>360キャッシュ不能なら問題はないのですが、 pre-expired な場合、状況によっては起源鯖による妥当性検証をスキップしてクライアントに送られてしまい、 他のクライアント向けの Cookie がそのクライアントに渡る可能性があることを指摘しています。
HTTP/1.1 に従っているなら Cache-Control: によりもっと細かく制御できるので大丈夫ということなのでしょう。

<meta http-equiv=Set-Cookie>

[39] <meta http-equiv=Set-Cookie> (Cookie setter 状態 >>38) は、 クッキーを設定するものです。

[40] この状態は不適合です >>38著者は使ってはなりません

[41] 利用者エージェントは、 content 属性があって空文字列でない場合、 content 属性値UTF-8符号化した値を文書の番地に関して「非HTTP」API から受信したものとして処理しなければなりません >>38

[54] かつてはストレージミューテックスを得ると規定されていましたが、誰も従っていませんでしtあ。

文脈

[84] Set-Cookie: の構文は curlコマンドラインオプション --cookie でも使われています。

[86] Set-Cookie: の構文は ffmpeg のオプション cookies でも使われています。 改行区切りとされています。 >>85

[85] FFmpeg Protocols Documentation (, ) https://ffmpeg.org/ffmpeg-protocols.html#http

cookies

Set the cookies to be sent in future requests. The format of each cookie is the same as the value of a Set-Cookie HTTP response field. Multiple cookies can be delimited by a newline character.

関連

[59] Perlモジュール HTTP::Cookie は、 クッキーファイルシステムに保存する際のデータ形式Set-Cookie3 という名称を使っています。

歴史

RFC 2109 の Set-Cookie:

[311] IETFCookie の標準化を試み、RFC 2109Netscape Cookie とは非互換な Set-Cookie: 頭欄を定義していました。

[351] 新旧 Cookie の互換性については、あまり役に立たない情報が多少 RFC 2109 の最後に載っています。詳しくは Cookie: の項の「歴史」の節をご覧ください。

仕様書

Set-Cookie2:

[308] RFC 2109 を廃止して代わりに発行された RFC 2965Set-Cookie を捨てて非互換な Set-Cookie2: 頭欄 を定義していました。

[353] RFC 2965 は (廃止した RFC 2109 には触れずに) Netscape Cookie との互換性について次のように規定していました。

[357] >>356 は新 Cookie による旧 Cookie の置き換えを命じていますが、 旧 Cookie による新 Cookie の置き換えには触れていません。

[370] Set-Cookie2:RFC 6265 により廃止されました >>369

[306] [JavaHouse-Brewers:31373] Re: Cookie.setMaxAge() について ( 版) http://java-house.jp/ml/archive/j-h-b/031373.html

  1. Cookie.serVersion(1)としたクッキーを送信した場合、 Set-CookieとSet-Cookie2ヘッダの両方がクライアントに送信されていました。
  2. NN4.7とIE5では、Set-Cookie2ヘッダはサポートしていないようです。

[307] IRC logs: freenode / #whatwg / 20090808 ( 版) http://krijnhoetmer.nl/irc-logs/whatwg/20090808#l-417

  • [18:02] <abarth> annevk42: if you're interested in the cookie stuff, you should join the mailing list and comment on the charter
  • [18:02] <abarth> annevk42: in general, i'm trying to keep the focus narrow
  • [18:03] <abarth> annevk42: speccing cookie2 is going to take a lot more work and a lot more time than speccing cookie0
  • [18:18] <annevk2> abarth, if you're going to spec cookies as implemented set-cookie2 is relevant, no?
  • [18:18] <abarth> annevk2: depends how widely its used
  • [18:18] <abarth> there was a recent message to the list
  • [18:19] <abarth> that suggested very few sites use it
  • [18:19] <abarth> i'm not sure we want to lock down the behavior of cookie2
  • [18:19] <annevk2> hmm, if we could actually get impl to remove support for it that'd be cool
  • [18:19] <abarth> which user agents implement it?
  • [18:20] <annevk2> I thougt set-cookie2, not cookie2, was implemented, but maybe not
  • [18:20] <abarth> i know they're in opera
  • [18:20] <abarth> but i'm not sure where else
  • [18:20] <annevk2> interesting
  • [18:22] <annevk2> if we're the only ones by all means don't spec it or simply say it's obsolete
  • [18:23] <annevk2> if we need extensions we can prolly extend cookie0 somehow once the processing model is written down
  • [18:23] <abarth> i don't think we want to say it's obsolete. cookie suck in a number of ways. it would be good to have a long term plan for how to dig ourselves out of the mess
  • [18:23] <abarth> yeah, that's a good point
  • [18:23] <abarth> that's what 2109 originally tried to do with Version=1
  • [18:24] <abarth> but i think they put the cart a bit in front of the horse
  • [18:24] <annevk2> besides rough consensus you need running code :p
  • [18:24] <annevk2> (also, versioning sucks :))

IETF のキャッシュ制御に関する規定

[330] RFC 2109RFC 2965 は以下のようなキャッシュ制御に関する規定がありました >>331, >>332

実装

[364] CGI::Cookie - search.cpan.org ( 版) http://search.cpan.org/~lds/CGI.pm-3.49/lib/CGI/Cookie.pm

Netscape Cookie 対応と銘打っていますが、 Max-AgeHttpOnly にもちゃんと対応しています。

[365] CGI::Simple::Cookie - search.cpan.org ( 版) http://search.cpan.org/~andya/CGI-Simple-1.112/lib/CGI/Simple/Cookie.pm

Netscape CookieHttpOnly に対応しています。 Max-Age には対応していません。

[362] Servlet::Http::Cookie - search.cpan.org ( 版) http://search.cpan.org/~ix/libservlet-0.9.2/lib/Servlet/Http/Cookie.pm

この Perlモジュールは、 RFC 2109 に基づいた Cookie API を提供しています。 Netscape CookieRFC 2109 の両方に対応しているようで、既定値Netscape Cookie になっています。

[366] Apache2::Cookie - search.cpan.org ( 版) http://search.cpan.org/~joesuf/libapreq2-2.12/glue/perl/lib/Apache2/Cookie.pm

CommentCommentURLExpires には対応していますが、 PortMax-AgeHttpOnly には対応していません。謎な実装です。

[363] Mojo::Cookie::Response - search.cpan.org ( 版) http://search.cpan.org/~kraih/Mojolicious-0.999926/lib/Mojo/Cookie/Response.pm

この PerlモジュールRFC 2965 の実装を名乗っています。 しかし CommentURL には対応しておらず、 ExpiresHttpOnly には対応しています (仕様違反?)。引用文字列Port 属性でのみ使います (仕様違反)。(対象は欄本体だけなので、 Set-Cookie2: にも Set-Cookie にも使えるようです。)

メモ

[1] 苦い開発: クッキーの有効期限の更新 ( 版) http://bitter-development.blogspot.com/2007/07/blog-post.html

Apache2.2 と IE6 でsetcookie()で既存の同じ名前と値を設定する場合、有効期限(期間)は更新されない。 有効期限0で一旦セットしてから同じ有効期間をセットする。

setcookie($name, $name, 0);
setcookie($name, $name, time()+60*60*24*365);

[367] Web Applications 1.0 r5486 Define http-equiv='set-cookie'Fixing http://www.w3.org/Bugs/Public/show_bug.cgi?id=9578 ( ( 版)) http://html5.org/tools/web-apps-tracker?from=5485&to=5486

[368] Apache HTTP Server Project ( ( 版)) http://httpd.apache.org/docs/1.3/misc/known_client_problems.html#cookie-merge

[383] HTTP::Cookies - search.cpan.org ( ( 版)) http://search.cpan.org/dist/HTTP-Cookies/lib/HTTP/Cookies.pm

[384] Apache2::Cookie - search.cpan.org ( ( 版)) http://search.cpan.org/dist/libapreq2/glue/perl/lib/Apache2/Cookie.pm

[385] KCP端末&SSLでクッキーが保存されない現象の覚書 - Kimura.Memo ( ( 版)) http://d.hatena.ne.jp/Kimura/20111210/p1

[386] co3k.org - Blog - 【情報求ム】au のガラケーで cookie が使えなくなる場合がある? ( ( 版)) http://co3k.org/blog/20

[387] Web Applications 1.0 r7414 Require Cookies and Origin if you implement HTTP. ( ( 版)) http://html5.org/tools/web-apps-tracker?from=7413&to=7414

[388] RFC 6787 - Media Resource Control Protocol Version 2 (MRCPv2) ( ( 版)) http://tools.ietf.org/html/rfc6787#section-6.2.15

[389] Bug 3420 – XMLHttpRequest does not handle set-cookie headers ( ( 版)) https://bugs.webkit.org/show_bug.cgi?id=3420

[390] Web Applications 1.0 r5486 Define http-equiv='set-cookie' ( ( 版)) http://html5.org/tools/web-apps-tracker?from=5485&to=5486

[391] draft-ietf-http-state-mgmt-errata-00 - HTTP State Management Mechanism (Errata) ( ( 版)) https://tools.ietf.org/html/draft-ietf-http-state-mgmt-errata-00

[392] Apache HTTP Server Project ( ( 版)) http://httpd.apache.org/docs/1.3/misc/known_client_problems.html#cookie-merge

[393] RFC Errata Report ( ( 版)) http://www.rfc-editor.org/errata_search.php?rfc=4229

[53] Cookies Lack Integrity: Real-World Implications | USENIX ( 版) https://www.usenix.org/conference/usenixsecurity15/technical-sessions/presentation/zheng

[55] Remove the storage mutex due to lack of implementation · whatwg/html@1b918cf ( 版) https://github.com/whatwg/html/commit/1b918cf72fcbba011f83b92ab5d1f483fb1cafa3

[56] Update integration with Encoding Standard · whatwg/html@6a31c26 ( 版) https://github.com/whatwg/html/commit/6a31c26cf12e39dab1a488e75dd56c03d6786d39

[57] Clarify the hooks into RFC6265 · whatwg/fetch@5a324a8 ( 版) https://github.com/whatwg/fetch/commit/5a324a891c42d42de09a01e03c3a063b9a4f882b

[58] Get multiple headers as an aray rather than a combined value? · Issue #506 · whatwg/fetch () https://github.com/whatwg/fetch/issues/506

[68] Creating Safari Content-Blocking Rules () https://developer.apple.com/library/content/documentation/Extensions/Conceptual/ContentBlockingRules/CreatingRules/CreatingRules.html#//apple_ref/doc/uid/TP40016265-CH2-SW1

block-cookies

The engine strips all cookies from the header before sending the request to the server. Safari's own privacy policy takes precedence, so that only cookies that would otherwise be accepted by the privacy policy can be blocked.

[69] Should "set response's CSP list" be in Main fetch? · Issue #364 · whatwg/fetch () https://github.com/whatwg/fetch/issues/364

[70] <meta http-equiv=set-cookie> is now a no-op (annevk著, ) https://github.com/whatwg/html/commit/9c135397caed7dd1a23d94ef43dcb372f89f853d

[71] <meta http-equiv=Set-Cookie> should do nothing if document is cookie averse · Issue #1950 · whatwg/html () https://github.com/whatwg/html/issues/1950

[72] Restrict <meta http-equiv=set-cookie> by annevk · Pull Request #3011 · whatwg/html () https://github.com/whatwg/html/pull/3011

[73] Remove <meta http-equiv=set-cookie> · Issue #3076 · whatwg/html () https://github.com/whatwg/html/issues/3076

[74] Block `<meta http-equiv="set-cookie" ...>` by chromium-wpt-export-bot · Pull Request #8531 · w3c/web-platform-tests () https://github.com/w3c/web-platform-tests/pull/8531

[75] Make <meta http-equiv=set-cookie> into a no-op by annevk · Pull Request #3649 · whatwg/html () https://github.com/whatwg/html/pull/3649

[76] Clarify how Headers does not support Set-Cookie (annevk著, ) https://github.com/whatwg/fetch/commit/7ab665e05e894f81d8ca741f7e7c19a334d88c08

[77] The comma-delimited combined value definition does not support Set-Cookie headers · Issue #345 · whatwg/fetch () https://github.com/whatwg/fetch/issues/345

[78] Clarify how Headers does not support Set-Cookie by annevk · Pull Request #714 · whatwg/fetch () https://github.com/whatwg/fetch/pull/714

[79] Note that cookies take effect despite CORS failures (Osintopsec著, ) https://github.com/whatwg/fetch/commit/d219389264742ce9bb3411601f680f54a77e2f3a

[80] Doc: failed CORS fetch with credentials should ignore Set-Cookie response header · Issue #855 · whatwg/fetch () https://github.com/whatwg/fetch/issues/855

[81] Change 3.2.6 Examples to reflect current state of implementations by Osintopsec · Pull Request #858 · whatwg/fetch () https://github.com/whatwg/fetch/pull/858

[83] Chrome80以降でALBの認証を使っているとcookieが4096バイトを超えて認証できないことがあり、社内サービスではcookie名を縮めて対応した - hitode909の日記 () https://blog.sushi.money/entry/2020/02/17/105927

[87] 3512 – REGRESSION (312-412): Can't log in to web mail site in Safari - www.spray.se () https://bugs.webkit.org/show_bug.cgi?id=3512