Cookieを一から理解する

# はじめに
この記事は[Webの基礎をおさらいカレンダー Advent Calendar 2022](https://qiita.com/advent-calendar/2022/basic_review)の2日目です。
このカレンダーでは、なんとなくわかった気になっている、Webの知識をおさらいするカレンダーです。
興味をもし持ってくださった方は、購読いただけると嬉しいです！

2日目は、Cookieについて紹介します。

## Cookieとは
Cookieとはなんでしょうか？  

一言で言えば
「Webサーバーから送信される、閲覧したユーザーの情報を一時的にブラウザに保存するためのデータ」を指します。

この説明だとなんのことかいまいちピンと来ない人もいると思うので、前提からおさらいしていきます。

### HTTP通信について
前提として、Webサーバとブラウザの間ではHTTP通信でやり取りが行われています。

HTTP通信についての具体的な説明はここではしませんが、
ブラウザからWebサーバーに対してこういう情報が欲しい！というリクエストが飛んで、
そのリクエストに対して、ブラウザに情報をレスポンスとして返却しているわけです。
![スクリーンショット 2022-12-03 23.15.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/463fec3f-aaf8-90cb-4559-ec68d1f3595f.png)

このHTTP通信の特徴の一つに、ステートレスというのがあります。
ステートレスというのはWebブラウザとやり取りした内容(状態)を覚えていないということです。

とあるカフェでの注文を例にして、具体的に説明すると、下記のようなイメージになります。
![スクリーンショット 2022-12-04 0.03.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/74376f41-4532-41c3-7aef-f2fb558511c8.png)

やり取りした内容を覚えていないので、ほげほげフラペチーノをお願いします、と前の会話で言っていても、
次のサイズ注文の時に、その前に伝えた情報も含めて渡してあげないといけないわけです。

ステートレスの場合、ユーザーのログイン情報だったり、カートに入れた商品の情報だったりを毎回毎回、リクエストに全て含める必要があります。
これでは、送信するデータ量が多くなってしまい、サーバパフォーマンスが低下してしまいます。

こうした背景から、ユーザーの状態管理を行うためにCookieという技術を使うわけです。

以下の図は、先ほどのカフェでの例をCookieを使って表現した例です。
![スクリーンショット 2022-12-04 1.01.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/67b4d258-86eb-e2ad-c5e5-7ce92247c48e.png)
先ほどと違うのは、一回目の注文時にメモを渡しているところです。
カフェの例だと、無駄なやり取りだなあと思うかもしれませんが、実際のWebのやり取りでは、
同時に大多数の人がリクエストをしてくるため、Webサーバーはブラウザ一つひとつの状態を管理していられないし、いつ再び注文が来るか分からない(下手したら数日後)ので、メモをWebサーバー側で持っておくのは非効率です。

こうした理由で、Webサーバーは一度アクセスしたユーザー情報の一時的な管理をするために
Cookieを発行してブラウザに保存しておくわけです。

では、実際にはどんな場面でCookieは利用されるのでしょうか。

### Cookieの役割
Cookieは、主に三つの用途で使用されます。

* セッション管理
    * ログイン情報、カート情報など
* パーソナライズ
    * ユーザー設定、テーマ(ダークモードなど)など
* トラッキング
    * ユーザーの行動記録や分析

セッションに関しての具体的な説明はここではしませんが、通信の始まりから終わりまでの一連の流れだと思ってください。
ECサイトなどで購入画面に進んだ後、何分か放置してから購入しようとするとセッションが切れました。というような表示を見たことがある方もいると思います。
Cookieでセッション管理する場合、Webサーバー側で発行されたセッションIDといった個人識別番号が発行され、Cookieに保存されます。
このセッションIDに有効期限があるので、ブラウザ側で再度操作した時に、サーバー側で確認して、もう使えないよーとなってたりするわけですね。

パーソナライズに関しては、例えばCookieにダークモードだよーという情報を保存してもらうことで、サイト内の別ページに遷移したとしてもCookieの値を見てダークモードを引き継ぐみたいなことをしています。

トラッキングについては後述のCookieの種類の箇所で説明します。

### Cookieの仕様
* key-valueの組み合わせで保持される(ex: userId=hogehoge)
* サーバーアクセスするたびに自動送信される
* Expiresで有効期限を設定できる
    * Cookieを保持する**ブラウザ側の**有効期限
* Path属性で、特定のパスに絞って有効化できる
* Domain属性で、Cookieを受信可能なホストを指定できる
    * 何も指定がない場合は、同じホストで、**サブドメインは除外される**
* HttpOnly属性を有効化するとJavaScriptでのDocument.cookie APIを使用できなくなる。
* Secure属性を有効化するとHTTPSでのリクエストのみ有効なCookieにできる。
* SameSite属性はサイト間でのリクエストが行われた際にCookieを行わないようにすることができる設定。
    * Strictでどんな場合であっても、サイト間のリクエストではCookieが送信されない。
    * Laxは、GETの場合のみ、サイト間でのリクエストであってもCookieが送信される。
    * Noneは制限なく送れるが、Secure属性の有効化が必要。
    * 何も設定しない場合はLaxが設定される。

### Cookieの種類
* First Party Cookie
    * サイトの運営者が発行するCookie
* Third Party Cookie
    * 第３者が発行するCookie
        * ドメインを横断してトラッキングを行うために使用される

Third Party Cookieは広告の効果測定やリターゲッティング広告で使われる。
この第三者が発行するCookieはブラウザでの制限がどんどん厳しくなってきています。
理由としては、プライバシー保護の観点からです。
特に、Safariでは`Intelligent Tracking Prevention`といったトラッキングの制限を行う機能が組み込まれています。

### Cookieの中身を見てみよう。

最後にCookieの中身を見てみましょう。
ChromeのWeb検証ツールを使います。
アプリケーションが表示されていない場合は>>をクリックした後、アプリケーションをクリックします。

![スクリーンショット 2022-12-04 2.36.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/111a703b-1948-ee40-50af-d7e1a83480d8.png)

qiita.comでの例です。
qiita.com以外のものはThird Party Cookieということになります。
先ほど説明したようにメインが異なるのでSameSiteがNoneになっています。
また、SameSite属性がNoneになっている箇所は全て Secureが有効化されていますね！


## まとめ
以上、Cookieの説明でした。
Webサイトを構築する上で、基本的な知識となるので、必ず押さえておきましょう！

[Webの基礎をおさらいカレンダー Advent Calendar 2022](https://qiita.com/advent-calendar/2022/basic_review)の2日目でした。
興味をもし持ってくださった方は、購読いただけると嬉しいです！

### 参考文献
[MDN HTTP Cookie の使用](https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies)