エンジニアを目指す初学者に向けて、わかりやすく解説したブログです。

ログインとセッション管理の流れを分かりやすく解説する

この記事ではわかりやすさ優先のため、厳密な説明を避けています。

セッションIDの役割

セッションIDとは、簡単に言うと「サーバーがユーザーIDを特定するためのヒント」である。

他の誰かがその文字列を見ても何かは分からないが、
サーバーはセッションIDとユーザーIDの対応表を持っているため、その文字列を見て誰のことだか理解できる。

セッション管理の流れ

1. ユーザーがログインする

まずはログインフォームなどから、ユーザーが入力したIDとパスワードを使ってDBに問い合わせを行う。

Image in a image block

2. サーバーがセッションIDとユーザー情報のペアを発行する

簡単に重複しないようなIDを発行し、そのIDとユーザーの簡易情報をKey-Valueのペアで格納する。

(今回は例として abc123xyzというセッションIDを発行)

Image in a image block

3. ユーザーに対してセッションIDを送る

先ほど発行したセッションID abc123xyzをHTTPレスポンスの Set-Cookie属性に入れてユーザー側に返却する。

Image in a image block

※わかりやすさのためにユーザーに送るものとRedisに保存するものを一緒にしたが、セキュリティ面ではそのまま使わない方がよい。
また、Secure属性やHttpOnly属性など、Cookieのセキュリティ面にも配慮しておく。

4. ユーザーがHTTPリクエストをするたびにセッションIDをサーバーに送る

ブラウザがSet-Cookieによってもらった情報は、
リクエストヘッダーの Cookie属性 を使って送信することができる。

RedisにセッションIDとユーザー情報の対応表があるので、「セッションID abc123xyzの人はユーザーIDが 1である」ということが分かる。

Image in a image block

5. DBからユーザーに関する詳細な情報を取得する

ユーザーIDが 1であることが分かったので、
そのIDを使ってユーザーDBからユーザー名など詳細な情報を取得することができる。

Image in a image block

セッションIDの保管方法

上記の説明では、一番オーソドックスな管理方法を説明したが
実はセッションIDの管理方法はいくつか存在する。

1. Redisなどの軽量DBに保存する

今回説明した方法であり、基本的には一番最初に選択肢として考えるものである。

RedisのようなKVSは、MySQLのようなRDBと比較して以下のような特徴がある。

  • 読み書きが高速
    • ログインユーザーの全てのリクエストで使われるので、早く読みたい
  • 複雑な検索はできず、「keyを指定してvalueを取得する」というシンプルな検索を提供する
    • 基本的に1:1のマッピングができればよい
  • TTL(保存したデータの有効期限)を設定可能
    • これが自動的にログイン状態の有効期限となる

デメリットとしては構築の面倒さや運用コストぐらいなので、特に理由がなければこの方法を選択したい。

2. サーバーのインメモリに保存する

Webサービスを配信しているサーバー自身にも、ある程度データを保存するとはできるので
サーバー上のメモリに簡易的に保管する方法も取ることができる。

実装が簡単である一方、以下のようなデメリットが存在する。

  • 2台以上のサーバーに増やすようなスケールができない
    • サーバーAで発行したセッションIDはサーバーBではマッピングが行えないため
  • リリース時に利用者のログイン状態がリセットされる
    • リリースするということは、サーバーが再起動するのでメモリがリセットされてしまうため

プログラミングの教本やプログラミングスクールはこの方法で教えているのが多いイメージ。

3. サーバー側ではなくクライアント側に保存する

ユーザー情報である {"id":1,"loginAt":"2025-03-20 15:30:00"}の文字列を
サーバー側の鍵を使って推測が難しい文字列に暗号化する。

f0e4c2f76c58916ecf1f8a5430a3b99f3d7f7a8e56b5d6a5c3b2e1c4d9a8b6e2

それをそのまま Set-Cookie属性に付与してクライアント側に送る。

鍵はサーバーしか持っていないので、鍵を知らない人は復号化して中身を見ることができないという仕組み。

これは結構簡単そうだが、以下のようなデメリットが存在することに注意。

  • Cookieのサイズが肥大化する
    • セッション管理しておきたい情報が増えると、Cookieサイズの上限に引っかかる可能性がある
  • 任意のタイミングでのセッション無効化が難しい
    • Redisならレコード削除=強制ログアウトなどができるが、Set-Cookieしかコントロール方法がない
  • 暗号化している秘密鍵が漏洩した場合、サービスを利用している全てのユーザーが危険にさらされるので影響範囲が大きい

後の2点はそんなに大きなデメリットではないが、
一般的なWebサービスではCookieサイズが問題になることがほとんどである。

まとめ

  • セッションIDは、サーバーがユーザーを識別するためのユニークなID
  • 基本的にはサーバー側で保管するのが良いが、クライアント側で保管することもできる