Cookieの基本

## Cookieとは

Cookieとは、ブラウザに保存される、ドメインと関連付けられたkey-valueペアのことである。



## Cookieを保存する方法

ブラウザにCookieを保存する方法は2つある。

* HTTPレスポンスヘッダーで保存する方法
* JavaScriptで保存する方法

### HTTPレスポンスヘッダーで保存する方法

[Set-Cookie HTTPレスポンスヘッダー](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie)でCookieを送ることで、ブラウザにCookieを保存できる。次の例では`a=apple`と`b=banana`の2つのCookieがブラウザに保存される。

```http
Set-Cookie: a=apple; path=/
Set-Cookie: b=banana; path=/
```

※`path=/`というのはCookieが有効なパスの指定である。普通は`path=/`でよいだろう。

HTTPレスポンスヘッダーで保存する方法では、Cookieはそれを送信したサーバーのドメインと関連付けられる。

### JavaScriptで保存する方法

JavaScriptでは、[document.cookie](https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie)にCookieをセットすることで、ブラウザにCookieを保存できる。次の例でも`a=apple`と`b=banana`の2つのCookieがブラウザに保存される。

```js
document.cookie = 'a=appple; path=/';
document.cookie = 'b=banana; path=/';
```

JavaScriptで保存する方法では、CookieはそのJavaScriptが実行されるページのドメインと関連付けられる。



## Cookieにアクセスする方法

ブラウザがHTTPリクエストをするとき、ブラウザはリクエスト先のドメインと関連付けられたCookieを[Cookie HTTPリクエストヘッダー](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie)で送る。サーバーではそれを読み取ることで、ブラウザに保存されたCookieにアクセスすることが可能である。

JavaScriptからもCookieにアクセスすることが可能である。次の例では、JavaScriptが実行されるページのドメインと関連付けられたCookieを取得している。

```js
const cookies = document.cookie;
// "a=apple; b=banana"のように";"で連結されたCookieが文字列として取得できる。
```



## Cookieの有効期限

Cookieの有効期限は、expires属性かmax-age属性で指定できる。（ただしmax-age属性は新しい属性で、サポート状況が怪しいので、expires属性を使う方がよいだろう。）

HTTPレスポンスヘッダーで保存する場合：

```http
Set-Cookie: a=apple; path=/; expires=Wed, 21 Oct 2015 07:28:00 GMT
```

JavaScriptで保存する場合：

```js
document.cookie = 'a=appple; path=/; expires=Wed, 21 Oct 2015 07:28:00 GMT';
```

expires属性もmax-age属性も指定されていないCookieは、ブラウザを終了したら削除される。そのようなCookieを**セッションCookie**と呼ぶ。



## httponly属性

次のように、CookieをHTTPレスポンスヘッダーで送るときにhttponly属性を付けると、そのCookieはJavaScriptからはアクセスできなくなる。

```http
Set-Cookie: a=apple; httponly; path=/
```

httponly属性により、悪意のあるJavaScriptからCookieを守ることができる。



## サードパーティCookie

昨今よく聞くサードパーティCookieとは、表示中のページから別ドメインのリソースを読み込むときに送受信されるCookieのことである。

### サードパーティCookieではない例

例えば、<http://my-domain/>に

```html
<script src="http://their-domain/setcookie.js"></script>
```

とあり、<http://their-domain/setcookie.js>に

```js
document.cookie = 'a=apple; path=/';
```

とあったとする。

<http://my-domain/>を表示すると、`a=apple`というCookieが**my-domain**に関連付けられて保存される。

`a=apple`というCookieを保存したのは別ドメインにあるJavaScriptだが、`a=apple`は表示中のページのドメインと関連付けられ、別ドメインには送られない。よって、`a=apple`はサードパーティーCookieではない。

### サードパーティCookieの例

例えば、<http://my-domain/>から<http://their-domain/setcookie.js>を読み込んだとき、次のHTTPレスポンスヘッダーが返ってきたとする。

```http
Set-Cookie: id=12345; path=/
```

このとき、`id=12345`というCookieが**their-domain**に関連付けられて保存される。このCookieは今後、<http://my-domain/>から<http://their-domain/setcookie.js>を読み込むときも、<http://your-domain/>から<http://their-domain/setcookie.js>を読み込むときも、HTTPリクエストヘッダーでtheir-domainのサーバーに送られるであろう。これがサードパーティーCookieである。

このサードパーティーCookieと[リファラー](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer)などにより、ユーザーの行動を追跡することが可能である。



## 参考文献

* [Cookie の仕様とセキュリティ](http://www.yunabe.jp/docs/cookie_and_security.html)
* [RFC 6265 — HTTP State Management Mechanism （日本語訳）](https://triple-underscore.github.io/RFC6265-ja.html)
* [HTTP cookies - HTTP | MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)