ウェブ開発を学んでいると必ず出てくる「HTTP はステートレス(状態を持たない)なプロトコルである」という言葉。 しかし、現実のウェブサイトでは、一度ログインすればページを移動しても自分だと認識され、ショッピングカートの中身も維持されます。
「状態を持たない」はずの HTTP を使って、どのようにして「ログイン状態」という状態を実現しているのか。その仕組みを整理しました。
結論:HTTP の「外」で状態を管理している
結論から言うと、HTTP プロトコル自体に状態を持たせるのではなく、**「サーバー側で状態を保持し、その識別子(ID)だけをリクエストごとにやり取りする」**ことで、擬似的にステートフルな振る舞いを実現しています。
基本的な流れは以下の通りです。
- ログイン成功時:サーバーが「この人は誰々さんだ」という情報をメモリやデータベース(セッション)に保存し、それを指し示す一意の ID(セッション ID)を発行する。
- クライアントへの保存:サーバーはレスポンスヘッダーを使って、クライアント(ブラウザ)にその ID を保存させる(主に Cookie を使用)。
- 以降のリクエスト:クライアントは、リクエストを送るたびに自動的にその ID をサーバーに添えて送る。
- 状態の復元:サーバーは届いた ID を元に、保存しておいたセッション情報を引き出して「あ、ログイン済みのユーザーだ」と判断する。
代表的な 2 つの管理方法
ログイン状態の管理には、大きく分けて「セッション方式」と「トークン方式」の 2 つがあります。
1. セッション + Cookie(サーバー側で管理)
最も伝統的で一般的な方法です。
- 仕組み:サーバー側のデータベースや Redis などにユーザーの情報を保持します。Cookie には、その情報を引き出すための「鍵」となるセッション ID だけを保存します。
- 特徴:
- サーバーが状態を管理するため、ログアウト処理(サーバー側のセッション削除)が確実に行える。
- セッション情報を保存するためのストレージ(DB や Redis)が必要。
2. トークン方式 / JWT(クライアント側で完結)
モダンな Web API やシングルページアプリケーション(SPA)でよく使われる方法です。
- 仕組み:ユーザー情報そのものを署名付きのトークン(JWT: JSON Web Token)に含め、クライアント側に持たせます。サーバーは届いたトークンの署名が正しいか検証するだけで、自分の手元にデータを持っておく必要がありません。
- 特徴:
- サーバーが状態を持たない(完全ステートレス)ため、スケールしやすい。
- 一度発行したトークンをサーバー側から強制的に無効化するのが難しいという課題がある。
なぜ「ステートレス」でも成立するのか
ここで重要なのは、**「HTTP はステートレスだが、アプリケーションはステートフルに振る舞える」**という点です。
HTTP がステートレスであることは、「各リクエストが前のリクエストを覚えている必要がない」というプロトコル上の制約に過ぎません。 しかし、リクエストヘッダーに識別子を含めることで、アプリケーション層(サーバー側のプログラム)が過去の文脈を復元することは自由です。
「リクエストごとに毎回自己紹介カード(Cookie やトークン)を提示している」と考えれば、HTTP 自体が記憶喪失であっても、やり取りが成立する理由がしっくりくるはずです。
まとめ
ログイン状態の維持は、HTTP プロトコルを拡張して実現しているのではなく、**「外部ストレージ + 識別子の受け渡し」**というアプリケーション側の工夫によって成り立っています。
「HTTP はステートレスである」という原則を理解した上で、その限界をどう補っているかを知ることは、セキュアでスケーラブルなウェブサイトを設計する第一歩と言えます。