Real World HTTPの2章2.5〜2.5.2クッキーに制約を与えるまで読んだ
クッキー
- クッキーは、ウェブサイトの情報をブラウザ側に保存する仕組みのこと
- HTTPのヘッダーをインフラとして実装されている
- HTTPはステートレスを基本に開発されているが、クッキーを使うことであたかもサーバーが状態を保持したステートフルであるかのように見えるサービスを提供できる
例 サーバーは最終アクセス日付と時間をクライアントに保存させたい
// サーバー → クライアントへのHTTPレスポンスのヘッダー // それぞれ名前=値の形式で送信する Set-Cookie: LAST_ACCESS_DATE=Jul/31/2019 Set-Cookie: LAST_ACCESS_TIME=12:04 // クライアントは上記のレスポンスの値を保存しておく // 次回アクセス時には次の送信し、サーバーはこの設定を読み取ることによってこのクラアントが最後にアクセスしてきた日時を知ることができる Cookie: LAST_ACCESS_DATE=Jul/31/2019 Cookie: LAST_ACCESS_TIME=12:04
クッキーの間違った使い方に関する注意
永続性の問題
- クッキーはどんな状況でも確実に保存される訳ではない。例えばシークレットモードのブラウザはサーバーからのクッキー保存の指示(
Set-Cookieヘッダー
)を無視することもあるし、セッション終了時にクッキーをリセットすることもある - リセットされるとデータが消失してしまうため、無くなっても問題ない情報、サーバー側の情報から復元できるデータ以外を格納する用途には向かない
- 同様の性質上、サーバー側のデータベースの代わりに使うこともできない
- クッキーはどんな状況でも確実に保存される訳ではない。例えばシークレットモードのブラウザはサーバーからのクッキー保存の指示(
容量の問題
- 最大容量は4KBと仕様で決まっているためそれ以上は送信できない
- クッキーはヘッダーとして常に通信に付与されるため、リクエスト、レスポンス双方の通信速度に影響を与える
セキュリティの問題
- HTTPの場合はクッキーは平文で送受信される(secureを付与すればHTTPSで暗号化された時にしか送受信されない)
- 暗号化されていたとしても、ユーザーから見えてしまうこと、ユーザー自身による書き換えが原理的に可能なことも問題
- システム側で必要となるようなIDや、書き換えられると誤動作に繋がるようなセンシティブな情報を入れるのには適さない
- 「認証した」という記録や、消えても問題ない情報だけをクッキーに入れるべき
クッキーに制約を与える
- クライアントはサーバーから受け取ったクッキーをローカルのストレージに保存する
- 同じURLにアクセスがあるときはそのクッキーを読みだしてサーバーへのリクエストヘッダーに加える
- クッキーは特定サービスのトークンとして利用されることが多く、誤ってクッキーを必要としないサーバーに送信することはセキュリティリスクを高める
- そのため、送信先を制御したりクッキーの寿命を設定するような属性がいくつか定義されている
- HTTPクライアントには、それらの属性を解釈し、クッキーの送信をコントロールする責務がある
クッキーの送受信を管理する属性
Expires, Max-Age属性
- クッキーの寿命を設定する
Domain属性
- クライアントからクッキーを送信する対象のサーバー。省略時はクッキーを発行したサーバーになる
Path属性
- クライアントからクッキーを送信する対象のサーバーのパス。省略時はクッキーを発行したサーバーのパスになる
Secure属性
- https接続での接続以外では、クライアントからサーバーへのクッキー送信を行わない
HttpOnly属性
- JavaScriptエンジンからクッキーを隠すことができる