ウェブ開発を学んでいると必ず出てくる「HTTP はステートレス(状態を持たない)なプロトコルである」という言葉。 しかし、現実のウェブサイトでは、一度ログインすればページを移動しても自分だと認識され、ショッピングカートの中身も維持されます。

「状態を持たない」はずの HTTP を使って、どのようにして「ログイン状態」という状態を実現しているのか。その仕組みを整理しました。

結論:HTTP の「外」で状態を管理している

結論から言うと、HTTP プロトコル自体に状態を持たせるのではなく、**「サーバー側で状態を保持し、その識別子(ID)だけをリクエストごとにやり取りする」**ことで、擬似的にステートフルな振る舞いを実現しています。

基本的な流れは以下の通りです。

  1. ログイン成功時:サーバーが「この人は誰々さんだ」という情報をメモリやデータベース(セッション)に保存し、それを指し示す一意の ID(セッション ID)を発行する。
  2. クライアントへの保存:サーバーはレスポンスヘッダーを使って、クライアント(ブラウザ)にその ID を保存させる(主に Cookie を使用)。
  3. 以降のリクエスト:クライアントは、リクエストを送るたびに自動的にその ID をサーバーに添えて送る。
  4. 状態の復元:サーバーは届いた 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 はステートレスである」という原則を理解した上で、その限界をどう補っているかを知ることは、セキュアでスケーラブルなウェブサイトを設計する第一歩と言えます。