Cookieの仕様は、Netscape Communications Corporation が、 http://wp.netscape.com/newsref/std/cookie_spec.html で公開しております。このドキュメントをfutomiが日本語化したものです。みなさまのCookieの理解に役立てれば幸いです。なお、緑色で記載された文章は、futomiが注釈として加筆したものです。また、一部、直訳ではなく、意訳した部分がございます。原文と表現がことなることがございますので、ご了承ください。
注意: この日本語訳は、futomiがCookieの理解を深めるために、自分なりに日本語にしたものです。本日本語訳には、翻訳上の誤りがある可能性があります。したがって、内容について一切保証をするものではありません。正確さを求める場合には、必ず原文を参照してください。当方は、この文書によって利用者が被るいかなる損害の責任を負いません。
もし誤りなどを見つけたら、こちらからご連絡いただければ幸いです。
クッキーは、CGIスクリプトのようなサーバ側コネクションにより、クライアント側に情報を保存させ、そしてそれを受け取るのに使うことができる一般的なメカニズムです。単純で永続的なクライアント側の状態を加えることによって、ウェブベースのクライアント/サーバアプリケーションの能力が大きく広がります。
サーバは、クライアントにHTTPオブジェクトを返す際、クライアントに保持してもらいたい状態情報を送ることができます。"状態オブジェクト"には、その状態が有効であるURLの範囲の記述が含まれています。その範囲に入るクライアントからの以後のHTTPリクエストは、クライアントからサーバに戻る状態オブジェクトの現在値の転送を含むでしょう。"状態オブジェクト"は、クッキーと呼ばれます。クッキーという名には、これといって大きな理由があるわけではありません)
この簡易的なメカニズムは、ウェブベースの環境のためにパワフルな新ツールを提供します。それは、新しいタイプのアプリケーションのホストに実装されることを可能にします。ショッピングアプリケーションでは、その時点で選択されている商品に関する情報を溜めることができます。料金サービスでは、ユーザーの登録情報を送り返すことができ、ユーザーは次に接続するときには、ユーザーIDを再度打ち直す必要がありません。また、クライアントにユーザーごとの好みを溜めることができ、サイトに接続するたびごとに、ユーザーの好みを表示させることができます。
HTTPヘッダーの一部としてSet-Cookieヘッダーを含めることによって、クッキーをクライアントに設定することができます。主に、CGIスクリプトによって生成されることになるでしょう。
Set-Cookie HTTP 応答ヘッダーの文法
これは、CGIスクリプトが、クライアントに設定したい新しいデータを、HTTPヘッダーに加えるのに使うフォーマットです。この設定したデータを今後、サーバ側で読み取ります。
Set-Cookie: NAME=VALUE; expires=DATE;
path=PATH; domain=DOMAIN_NAME; secure
- NAME=VALUE
-
ここには、セミコロン、カンマ、スペースを排除した文字列が入ります。セミコロン、カンマ、スペースが含まれるようなデータを設定する必要がある場合には、URLエンコードのような何かしらのエンコードが推奨されます。ただし、エンコード自体は、まったく定義されているわけではありませんし、要求されるものではありません。(日本語を扱う場合には、URLエンコードをする必要があります。)
Set-Cookieヘッダーには、この属性は必ず必要です。その他の属性は必須ではありません。
- expires=DATE
-
expires属性には、クッキーの有効期限を定義する日付の文字列を設定します。一度、有効期限に達すると、クッキーはクライアントに保存されません。もしくはクライアントからサーバに送信されません。
日付文字列のフォーマットは以下のとおりです。
Wdy, DD-Mon-YYYY HH:MM:SS GMT
これは、RFC 822, RFC 850, RFC 1036, RFC 1123に基づいています。ただし、法定タイムゾーンは、GMTのみです。また日付の各要素間は、ダッシュ(「-(ハイフン)」のこと)で区切られなければいけません。
注意: Netscape Navigator version 1.1 以前ではバグがあります。クッキーに、path属性が明示的に"/"と設定されないと、セッション間で、expires属性が適切に保存されません。
- domain=DAMAIN_NAME
-
クッキーリストから有効なクッキーを探す際、リクエストするURLのホストのドメイン名を使って、クッキーのdomain属性の比較が行われます。もし、ドメインが後方一致した場合には、pathマッチングを行い、クッキーを送信すべきかを判別します。"後方一致"とは、domain属性が、ホストの完全修飾ドメイン名(Fully Qualified Domain Name)の尾部に対して一致したということです。たとえば、"acme.com"のdomain属性は、"anvil.acme.com"というホスト名に一致しますし、"shipping.crate.acme.com"も同様に一致します。
特定されたドメイン内のホストだけは、一つのドメインに対してクッキーを設定することができます。そして、ドメインは、".com", ".edu", "va.us"のような形式のドメインを除いて、ドメイン名の中に少なくとも2つか3つのピリオドを含んでいなければいけません。以下に示す7つの特別なトップレベルドメインに含まれないドメインのうち、いくつかは2つのピリオドが必要となり、それ以外のドメインは、少なくとも3つ必要です。7つの特別なトップレベルドメインは、次のとおりです。:"COM", "EDU", "NET", "ORG", "GOV", "MIL", "INT"(Cookieの仕様が作成された時代は、7つのドメインだけでしたが、現在は、汎用ドメインも使われるようになり、この限りではありません。)
domainのデフォルト値は、クッキー応答を生成したサーバのホスト名です。
- path=PATH
-
path属性は、クッキーが有効なドメインのURLのサブセットを特定するのに使われます。クッキーがあるdomainにマッチすると、URLのパス名の要素がpath属性と比較されます。そして、一致したなら、クッキーは有効とみなされ、URLリクエストと一緒に送られます。"/foo"というパスは、"/foobar", "/foo/bar.html"に一致します。"/"というパスは、もっとも一般的なパスです。
もし、pathが特定されていない場合は、クッキーを含んでいるヘッダによって記述されているドキュメントと同じパスとみなされます。
- secure
-
もしクッキーがsecureとマークされていたなら、そのクッキーは、ホストとの通信チャネルが安全なチャネルの場合にのみ送られます。現在においては、secureクッキーは、HTTPS(HTTP over SSL)サーバのみに送られる場合を意味します。
もし、secure指定がない場合には、クッキーは安全とみなされ、安全でないチャネルを通して明文で送られます。
Cookie HTTP Request Headerの文法
ブラウザーは、HTTPサーバからURLを要求する際に、保持しているすべてのクッキーに対してそのURLを検索します。そして、もし一致したなら、すべての一致したクッキーの name/valueペアーを含む1行をHTTPリクエストに含めます。フォーマットは以下のとおりです。
Cookie: NAME1=OPAQUE_STRING1; NAME2=OPAQUE_STRING2 ...
補足
- 一つのサーバ応答に対して、複数のSet-Cookieヘッダーを発行することができます。
- 同じパスと名前のインスタンスは、優先する最後のインスタンスにお互い上書きされます。パスが同じで名前が異なるインスタンスは、付加マッピングを追加します。
- 上位層にパスを設定すると、他の下位層のパスマッピングを上書きしません。もし与えられたクッキー名に対して複数一致しても、パスが異なれば、すべての一致したクッキーが送られます。(例を参照)
- expiresヘッダーによって、クライアントは、マッピングのパージ(浄化)がいつ安全になるのかを判別します。しかし、クライアントは、そうすることを要求されません。 もしクッキーの数が限界を超える場合においても、有効期限に達する前にクッキーを削除するかもしれません。
- サーバにクッキーを贈る際に、下位層まで指定されたパスのクッキーは、その上位層までしか指定されていないパスのクッキーより先に送られなければいけません。たとえば、"name1=foo"で、パスが"/"のクッキーは、"name1=foo2"でパスが"/bar"のクッキーの後に送られるべきです。
- クライアントが一度に溜めておくことができるクッキーの数には限界が存在します。これは、クライアントが受け取り保存するために用意されるべきクッキーの最小数の仕様です。
- クッキーの数は、トータルでで300まで。
- 一つのクッキーにつき4KBまで。name と OPAQUE_STRING は、4KBまでの形式に結合されます。.
- サーバもしくはドメインごとに、クッキーの数は20まで。 (特定されたホストやドメインは、別々のエンティティーとして扱われ、各々(結合されたものではない)クッキーの数は20までということに注意してください。)
サーバは、クライアントに、これらの限界を超えることがありうることを期待すべきではありません。300クッキー限度や20クッキー/サーバ限度を超えた場合、クライアントは、もっとも過去に使われたクッキーを削除すべきです。4KBを超えるクッキーに出くわした場合には、クッキーは、フィットするように切り取られるべきです。しかし、名前は、クッキーが4KB以下である限り、手を加えるべきではありません。
- もし、CGIスクリプトからクライアントのクッキーを削除したい場合には、同じ名前で、過去の有効期限を持ったクッキーを返すことによって実現できます。パスと名前は、有効なクッキーを満了したクッキーに置き換えるために、正確にマッチしなければいけません。この仕様により、クッキーの発信元でなければ、クッキーを削除することが難しくなります。
- proxyサーバがHTTPを受け取る場合、Set-cookie応答ヘッダーは、決して受け取るべきではありません。
- もし、proxyサーバがSet-Cookieヘッダーを含んだ応答を受け取った場合には、たとえ、応答が304(Not Modified)か、200(OK)かどうかに関わらず、Set-Cookieヘッダーをクライアントに伝達すべきです。
同様に、もしクライアント要求がCookieヘッダーを含んでいる場合、クライアント要求は、proxyをスルーしてしまわなければいけません。たとえ、条件付のIf-modified-since 要求が作られたとしても。
クッキーの利用を説明するために、いくつかのやりとりの例を挙げます。
以下に掲載している例は、原文そのままですが、「有効期限」の西暦が下2桁となっています。しかし、実際には、4桁で定義する必要があります。たとえば、2001年であれば、「01」ではなく、「2001」とします。
例1
クライアントがサーバにドキュメントを要求し、サーバから以下のレスポンスを受け取る。
Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT
次に、クライアントがこのサーバ上のパス"/"のURLを要求するとき、クライアントは以下のCookie情報をサーバに送る。
Cookie: CUSTOMER=WILE_E_COYOTE
再度、クライアントがサーバにドキュメントを要求し、サーバから以下のレスポンスを受け取る。
Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
次に、クライアントがこのサーバ上のパス"/"のURLを要求するとき、クライアントは以下のCookie情報をサーバに送る。
Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
次にクライアントが、サーバから以下のCookie情報を受け取ったとする。
Set-Cookie: SHIPPING=FEDEX; path=/foo
クライアントがこのサーバ上のパス"/"のURLを要求するとき、クライアントは以下のCookie情報をサーバに送る。
Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
クライアントがこのサーバ上のパス"/foo"のURLを要求するとき、クライアントは以下のCookie情報をサーバに送る。
Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX
例2
例1からのすべてのCookie情報のマッピングは、クリアされたと仮定します。
クライアントがサーバから以下のCookie情報を受け取ります。
Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
クライアントがこのサーバ上のパス"/"のURLを要求するとき、クライアントは以下のCookie情報をサーバに送る。
Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001
次に、クライアントがサーバから以下のCookie情報を受け取ったとする。
Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo
クライアントがこのサーバ上のパス"/ammo"のURLを要求するとき、クライアントは以下のCookie情報をサーバに送る。
Cookie: PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001
注意: "/ammo"マッピングに加えて"/"マッピングの継承によって、"PART_NUMBER"と名づけられた二つの name/value のペアーが存在します。