HTTPQUERY
日本語

Set-Cookie

使い方

Set-Cookie ヘッダーは、cookie のスコープ、寿命、セキュリティ上の性質を制御する任意の属性とともに、名前と値の組を保存するようクライアントに指示します。1 つの Set-Cookie ヘッダーが設定する cookie はちょうど 1 つです。複数の cookie を送るサーバーは、同じレスポンスに複数の Set-Cookie ヘッダーを含めます。

一般的な構文は、イコール記号で区切られた cookie の名前と値、その後にセミコロンで区切られた任意の属性が続く形です。

Set-Cookie: <name>=<value>; <attributes>

cookie の名前は、制御文字、スペース、タブ、および区切り文字 ( ) < > @ , ; : \ ” / [ ] ? = { } を除く US-ASCII の文字を受け付けます。cookie の値は、制御文字、空白、二重引用符、カンマ、セミコロン、バックスラッシュを除く US-ASCII の文字を受け付けます。値は任意で二重引用符で囲めます。

ブラウザは、Fetch API や XMLHttpRequest を通じてフロントエンドの JavaScript が Set-Cookie ヘッダーを読み取るのをブロックします。このヘッダーは Fetch の仕様において禁止レスポンスヘッダー名です。CORS のレスポンスに含まれる cookie は、リクエストが認証情報を含まない限り無視されます。

cookie 名の接頭辞は、ブラウザが強制する追加の制約を課し、その cookie がどこでどのように設定されたかについての保証を与えます。

__Secure- の接頭辞は、Secure 属性と HTTPS のオリジンを必要とします。これにより、HTTP のみのサイトがセキュアな cookie と同じ名前の cookie を設定するのを防げます。

Set-Cookie: __Secure-ID=abc; Secure; Path=/

__Host- の接頭辞はさらに厳しい要件を加えます。Secure 属性があること、Domain 属性がないこと、Path が / に設定されていることです。これにより cookie が正確なオリジンのホスト名に束縛され、サブドメインからの干渉を防げます。

Set-Cookie: __Host-ID=abc; Secure; Path=/

__Http- の接頭辞は Secure と HttpOnly の両方の属性を必要とし、JavaScript からではなく Set-Cookie ヘッダーを通じてのみ設定できます。

Set-Cookie: __Http-ID=abc; Secure; HttpOnly

__Host-Http- の接頭辞は __Host- と __Http- の両方の制約を組み合わせ、利用可能な中で最も厳格な cookie の束縛を作ります。

Set-Cookie: __Host-Http-ID=abc; Secure; HttpOnly; Path=/

注意

__Http- と __Host-Http- の接頭辞は、ブラウザが広く強制している既存の __Secure- と __Host- の接頭辞とは別の、独立した cookie 接頭辞の提案に由来します。これらの新しい接頭辞は提案段階にとどまっています。

SEO への影響

Googlebot はオリジンが cookie を設定した場合にはそれを送信しますが、個別のクロールセッションをまたいで cookie を保持することはありません。アセット用ドメインで大きな cookie を使うと、レンダリング中のリクエストサイズが増大します。静的アセットに cookie を使わないドメインを用いることで、このオーバーヘッドを回避できます。クローラーがページを見られなくなるような、cookie に依存するロジックでコンテンツを閉ざすことは避けてください。

Expires

Expires 属性は、HTTP-date 形式で絶対的な有効期限を設定します。この日付を過ぎると、クライアントはその cookie を送らなくなります。Max-Age とともに省略された場合、その cookie はクライアントの終了時に削除されるセッション cookie になります。ブラウザはレスポンスの Date ヘッダーを使って時計のずれを調整します。

Expires=Thu, 31 Dec 2026 23:59:59 GMT

注意

ブラウザは Expires の値を、cookie が設定された時点から 400 日までに制限します。この上限により、およそ年に 1 回訪れるようなサイトでも cookie を維持できる一方、無期限の保持は防がれます。

Max-Age

Max-Age 属性は、クライアントがレスポンスを受け取った時点からの cookie の寿命を秒で設定します。0 または負の値は cookie を直ちに失効させます。Expires と Max-Age の両方が存在する場合、Max-Age が優先されます。

Max-Age=2592000

JavaScript の Cookie Store API も cookieStore.set() メソッドを通じて maxAge のオプションを公開しており、プログラムからの cookie 管理のためにこの属性を反映しています。この API では、同じ cookie に expires と maxAge の両方を設定することはできません。

注意

ブラウザは Max-Age の値を 400 日(34,560,000 秒)に制限しており、これは Expires の上限と一致します。

Domain

Domain 属性は、どのホストがその cookie を受け取るかを指定します。設定された場合、cookie は指定されたドメインとそのすべてのサブドメインで利用できます。省略された場合、cookie は既定で発行元の正確なホストに限定され、サブドメインは除外されます(ホスト専用の cookie)。有効なのは現在のドメインか、現在のホストの親ドメインだけです。先頭のドットは無視されます。

Domain=example.re

Path

Path 属性は、指定した URL のパス接頭辞に一致するリクエストへ cookie の送信を限定します。スラッシュ / がパスのセグメントを区切ります。Path=/docs の cookie は /docs、/docs/、/docs/Web/HTTP に一致しますが、/ や /docsets には一致しません。

Path=/

注意

Path 属性はセキュリティの仕組みではありません。同一オリジンのスクリプトは、パスの制限に関わらずすべての cookie にアクセスできます。

Secure

Secure 属性は cookie を HTTPS の接続に限定します。ブラウザは、暗号化されていない HTTP でセキュアな cookie を送ることは決してありません。セキュアでないオリジンは、この属性を持つ cookie を設定できません。開発中の localhost は HTTPS の要件から除外されます。

HttpOnly

HttpOnly 属性は、document.cookie、Cookie Store API、その他の DOM インターフェースを通じた cookie への JavaScript のアクセスをブロックします。JavaScript が fetch() や XMLHttpRequest で開始した HTTP リクエストでは、cookie は引き続き送られます。この属性は、cookie の値を盗もうとするクロスサイトスクリプティング(XSS)攻撃を緩和します。

SameSite

SameSite 属性は、クロスサイトのリクエストでブラウザが cookie を送るかどうかを制御します。3 つの値が定義されています。

Strict は、同一サイトのリクエストでのみ cookie を送ります。外部サイトのリンクをクリックする場合を含め、クロスサイトのナビゲーションでは cookie は含まれません。

Lax は、同一サイトのリクエストと、URL バーが変わるクロスサイトのトップレベルナビゲーションで cookie を送ります。サブリソースのリクエスト、fetch() の呼び出し、iframe のナビゲーションでは cookie は含まれません。SameSite 属性が指定されていない場合、ほとんどのブラウザは既定で Lax を採用します。

None は、クロスサイトのリクエストを含むすべてのリクエストで cookie を送ります。SameSite=None を使う場合は Secure 属性が必要です。異なるスキーム(HTTP と HTTPS)からの cookie はクロスサイトとして扱われます。

SameSite=Lax

Partitioned

Partitioned 属性は、cookie のオリジンとトップレベルのサイトの両方をキーとする分離されたストレージに cookie を保存します。shop.example.org に埋め込まれた cdn.example.re が設定した分離 cookie は、cdn.example.re が shop.example.org に埋め込まれているときにのみ送られ、他のサイトに埋め込まれているときには送られません。

この属性は Cookies Having Independent Partitioned State(CHIPS)の提案の一部です。この属性により、埋め込みウィジェット、CDN の負荷分散、ヘッドレス CMS のプロバイダーといった正当なクロスサイト cookie の用途を、完全なクロスサイトトラッキングの能力を与えることなく実現できます。

Secure 属性が必要です。cookie を正確なオリジンに束縛するため、__Host- の接頭辞が推奨されます。

Set-Cookie: __Host-sess=abc; SameSite=None; Secure; Path=/; Partitioned

Chromium ベースのブラウザと Firefox でサポートされています。Safari は別の仕組みによって既定でサードパーティ cookie を分離しており、この属性は使いません。

例

有効期限の属性を持たないセッション cookie です。クライアントのセッションが終了すると、この cookie は削除されます。

Set-Cookie: sessionId=38afes7a8

30 日の寿命を持つ永続的な cookie です。Max-Age 属性が現在時刻からの相対で有効期限を設定します。

Set-Cookie: id=a3fWa; Max-Age=2592000

認証トークンに適したセキュリティ属性を持つ cookie です。HttpOnly 属性が JavaScript からのアクセスをブロックし、Secure が HTTPS に限定し、SameSite=Strict がクロスサイトでの送信を防ぎます。

Set-Cookie: __Host-token=eyJhbGci; Secure; HttpOnly; SameSite=Strict; Path=/

クロスサイトの埋め込み向けの分離されたサードパーティ cookie です。Partitioned 属性が、その埋め込みが現れる特定のトップレベルサイトに cookie を隔離します。

Set-Cookie: __Host-embed=34d8g; SameSite=None; Secure; Path=/; Partitioned

1 つのレスポンスで複数の cookie を設定します。各 cookie にはそれぞれ独自の Set-Cookie ヘッダーが必要です。

Set-Cookie: theme=dark; Path=/; Max-Age=31536000
Set-Cookie: __Host-sid=x8Kp2; Secure; HttpOnly; SameSite=Lax; Path=/

トラブルシューティング

cookie が保存されない、あるいは意図しないリクエストに付いてくるといった問題は、属性の食い違いやブラウザの強制ポリシーにさかのぼれることがよくあります。

HTTP で Secure フラグを付けたために cookie が保存されない。Secure 属性は HTTPS の接続を必要とします。平文の HTTP で Secure を付けて設定された cookie は、黙って破棄されます。ブラウザのアドレスバーでプロトコルを確認し、DevTools の Network タブで Set-Cookie ヘッダーを調べてください。開発中の localhost はこの制約から除外されます。

クロスサイトのリクエストで cookie が送られない(SameSite の既定)。現代のブラウザは、SameSite 属性がない場合に既定で SameSite=Lax を採用します。fetch() の呼び出し、iframe、画像の読み込みといったクロスサイトのサブリクエストでは cookie は含まれません。cookie をクロスサイトで送る必要がある場合は SameSite=None; Secure を加えるか、クロスサイトへの依存を避けるようフローを組み直してください。

cookie のパスの不一致。Path=/app で設定された cookie は、/api や / を対象とするリクエストには送られません。cookie を必要とするリクエストのパスと Path の値が一致していることを確認してください。Path=/ を設定すると、cookie はサイト全体で利用できるようになります。

Domain 属性のスコープの問題。Domain=sub.example.re で設定された cookie は example.re には送られません。Domain 属性を省略すると、正確なホスト名に限定されたホスト専用の cookie になります。値の先頭のドットはブラウザに無視されます。保存された各 cookie の実効ドメインを調べるには、DevTools の Application > Cookies のパネルを使ってください。

ブラウザのプライバシー機能によってサードパーティ cookie がブロックされる。Safari は Intelligent Tracking Prevention により既定でサードパーティ cookie をブロックします。Firefox の Enhanced Tracking Protection と Chrome の Privacy Sandbox も同様の制限を適用します。Partitioned 属性(CHIPS)は、正当なクロスサイト cookie の用途に対する標準に基づいた道筋を提供します。挙動を確認するため、複数のブラウザでテストしてください。

cookie が最大サイズを超える。ブラウザは 1 つの cookie につきおよそ 4096 バイト(名前、値、属性の合計)の上限を強制します。サイズを超えた cookie は黙って破棄されます。大きなペイロードはサーバー側のセッションへ移し、cookie にはセッション識別子だけを保存してください。

保存された cookie をデバッグする。DevTools > Application > Cookies を開くと、属性、有効期限、サイズを含め、現在のサイトのすべての cookie を調べられます。document.cookie の API は HttpOnly の cookie を公開しません。サーバーが返す生の Set-Cookie ヘッダーを見るには curl -v を使ってください。