k-tokitoh

cookie

2025-11-15

ブラウザは cookie をたくさんもっている。

「あるリクエストに cookie が付加されるかどうか」は、以下で判断される。

基本的な条件

domain

リクエストの送信先 domain と、cookie の domain 属性を照合して判断する。

domain とはスキーマやポートを含まない情報(ex. foo.com)である。

  • Set-Cookie で domain 属性を指定しない場合
    • Set-Cookie するレスポンスを返したサーバと同一の domain へのリクエストにのみ付加される
    • chrome dev tools では domain 欄にドットなしで表示される。
  • Set-Cookie で domain 属性を指定する場合
    • 指定した場合、指定した domain 及びその配下の全ての sub domain へのリクエストに付加される。
    • Set-Cookie するレスポンスを返したサーバと同一の domain、または親 domain のみを指定できる。
    • chrome dev tools では domain 欄にドットつきで表示される。
  • 上記の結果として、指定しない場合に最も制約が強くなる。(指定する形で、指定しない場合と同等の制約をつけることはできない..!)
  • chrome dev tools での表示はちょっとややこしい。domain 属性が未指定ならばfoo.comと表示され、domain 属性がfoo.comと指定されたら.foo.comと表示される。

path

  • 原則
    • cookie の path の値と一致するか、その配下の path へのリクエストに付加される。
      • ex. /fooが指定された場合、/foo, /foo/aには付加されるが、/barには付加されない。
  • 指定しない場合
    • Set-Cookie するレスポンスの元になるリクエストの path のうち、最後の/より前の部分が path 属性に設定される。
      • ex. /foo/barへのリクエストのレスポンスで Set-Cookie された場合、cookie の path 属性は/fooになる
      • ex. /foo/bar/へのリクエストのレスポンスで Set-Cookie された場合、cookie の path 属性は/foo/barになる
    • これはブラウザのデフォルトであり、サーバ側のライブラリでデフォルトが異なる可能性があるので注意すること。

追加的な条件

⚠️ secure, samesite は、「リクエストの送信において cookie を参照/付加するか」という点だけでなく、そもそも「ブラウザに cookie を保存するか」という点にも影響する。 条件としては同等で読み替えれば解釈可能なので、前者のみを記述する。

secure 属性

リクエストのスキームが https である場合のみ cookie を付加する。

samesite 属性

前提 1

  • サイトとはスキーム(ex. http, https)と eTLD+1 の組み合わせ
  • eTLD(effective top level domain)とは、広くその domain 配下に登録可能とされるような domain のこと
  • eTLD+1 とは、eTLD の 1 階層下の sub domain
    • ex. foo.com, foo.co.jp

前提 2

あるリクエストの送信元とは以下。

  • html の各種タグ(ex. a, form, iframe, img, script)から送信される場合、その html の配信元
  • js から送信される場合、その js を読み込む起点となった html の配信元
    • ex. foo.comから配信された html の script タグでbar.comの js を読み込み、そこでリクエストを行った場合、リクエストの送信元はfoo.comになる

種類

  • Strict
    • あるリクエストの送信元と、そのリクエストの送信先が同一サイトである場合のみ cookie が付加される
  • Lax
    • Strict に加えて、以下の場合に cookie が付加される
    • ブラウザのアドレスバーの URL が変わる遷移の場合には、リクエストの送信元と、そのリクエストの送信先が同一サイトでなくても cookie を付加する
    • 例えば以下の例で役立つ
      • foo.comでは cookie による認証を行っている
      • あるユーザーが、foo.comにログインした(foo.comを domain 属性にもつ認証情報の入った cookie がブラウザに保存される)
      • そのユーザーが、bar.comでの<a href='foo.com'>window.location.href = 'foo.com'で foo.com に遷移する = foo.com へのリクエストを送信する
      • そのリクエストは送信元のbar.comと送信先のfoo.comが異なるが、そのリクエストにはfoo.comを domain 属性にもつ cookie が付加される
      • これにより、ユーザーはfoo.comにアクセスした際に、ログイン済みユーザーとしてのレスポンスを受け取ることができ、スムースな遷移体験が実現する
  • None
    • あるリクエストの送信元と、そのリクエストの送信先が同一サイトでなくても cookie が付加される(=サイトに関する制約がない)
    • この値に設定するためには secure 属性が必要

その他

httponly 属性

js からその cookie を read/write できるかということ。

httponly だと js からは write もできず、削除するにはサーバからのレスポンスで以下のいずれかが必要。

  • 空の値を set する
  • expire に過去の日付を入れる(ブラウザが判断して消してくれる)

chrome devtools での表示

chrome devtools での表示について。 application タブの Storage > Cookie の項目はそれぞれ、オリジン(ex. https://localhost:4200)で表記される。 しかしその内容としては、ブラウザがもつ cookie 全体のうち、その項目に当てはまる domain(ex. localhost)のものを全て表示する。

そのため、例えば以下のようなことが起こる。

  • タブ A でhttps://localhost:4200を開くと、そのタブの dev tools にはhttps://localhost:4200という項目が表示される
  • タブ B で全く別のアプリケーションにhttp://localhost:8000(スキーマもポートも異なる)でアクセスして、ブラウザにlocalhostdomain の cookie が set された
  • タブ A の dev tools のhttps://localhost:4200という項目には、上記の cookie も表示される
  • 実際、タブ A でhttps://localhost:4200により配信されたドキュメントからlocalhostへのアクセスをする場合(:4200向きでも:8000向きでも、または別の:8080向きでも)、諸々の条件を満たすならばその cookie は送信される

補記

個人的なメモという側面が強いことを踏まえて、RFC 等の典拠は最小限に留めています。