Webサーバー・インフラ
セッション(Session)
post:
セッションは、HTTPリクエストをまたいで利用者ごとの状態をサーバー側で扱う仕組みです。 ログイン状態や権限、一時的な操作の進行状況を、一定期間だけリクエストと結び付けるために使います。
セッションとは?
HTTPはステートレスなプロトコルです。個々のリクエストだけを見ても、サーバーはそれが以前のどのリクエストと同じ利用者によるものかを、HTTPだけからは判断できません。 セッション管理では、サーバーが利用者ごとの状態にセッションIDを対応付け、後続のリクエストで受け取ったIDを手掛かりに状態を取り出します。
セッションIDは利用者を識別するための値であり、利用者名や権限そのものではありません。 実データはサーバー側のセッションストアに置き、ブラウザ側には推測されにくいIDだけを渡す構成が一般的です。
Cookieとの違い
セッションは「利用者ごとの状態をどこで、いつまで有効にするか」というアプリケーション側の仕組みです。 対してCookieは、ブラウザが値を保存し、条件に合うHTTPリクエストでその値を送る仕組みです。
多くのWebアプリケーションでは、セッションIDをCookieに入れて運びます。しかしCookieはあくまでIDの運び手であり、Cookieの有無だけではログイン状態は決まりません。 サーバーがIDを検証し、有効なセッションを取得できたときに初めて、ログイン済みとして扱えます。Cookieの送受信や属性については、Cookie(クッキー)の解説を参照してください。
基本的な流れ
- 利用者がログインなどの操作を行い、サーバーが認証結果を確認する
- サーバーが予測困難なセッションIDを発行し、利用者ID、権限、発行時刻、有効期限などの状態をサーバー側のストアに保存する
- ブラウザは、通常はCookieを使って後続のリクエストにセッションIDを添える
- サーバーはIDと有効期限を検証し、対応する状態を取得して、そのリクエストを処理する
- ログアウト、期限切れ、管理者による無効化などでサーバー側のセッションを失効させる
重要なのは、ブラウザから送られたIDをそのまま信用しないことです。 IDが存在するか、有効期限内か、無効化されていないかをサーバー側で確かめます。
セッションの有効期限
セッションの期限は、セッションIDを保存するCookieの期限とは別に、サーバー側で管理します。 Cookieがブラウザに残っていても、対応するサーバー側のセッションが失効していれば、そのIDでログイン状態を復元してはいけません。
| 種類 | 失効の基準 | 目的 |
|---|---|---|
| アイドルタイムアウト | 最後のリクエストから一定時間が経過する | 操作されていない端末でセッションが使われ続ける時間を短くする |
| 絶対タイムアウト | セッション発行から一定時間が経過する | 利用が続いていても、同じログイン状態を無期限に保たない |
| 明示的な無効化 | ログアウト、パスワード変更、権限変更、管理者の操作など | 必要な時点で再認証を求め、古いセッションを使えなくする |
「ブラウザを閉じたらログアウトする」という挙動だけに依存する設計は安全ではありません。 ブラウザの復元機能やCookieの保存方法は利用環境により異なるため、認証状態の最終判断はサーバー側の期限と無効化処理で行います。
セッションの保存先と複数台構成
セッションストアには、アプリケーションプロセスのメモリ、共有のインメモリデータストア、データベースなどを使えます。 保存先を選ぶときは、応答速度だけでなく、再起動時の扱い、期限切れデータの削除、可用性、運用できる規模を考えます。
Webサーバーが複数台ある構成では、リクエストごとに異なるサーバーへ届くことがあります。 そのため各サーバーのプロセス内だけに状態を持たせる場合は、同じ利用者が別のサーバーへ振り分けられたときにセッションを取得できない可能性があります。 共有ストアを使う、または振り分けを固定する設計にするなど、セッションをどのサーバーで参照できるかを決めておく必要があります。
ログアウトとセッションの破棄
ログアウト時は、サーバー側でセッションを削除または無効化し、ブラウザに残るセッションIDのCookieも期限切れにします。 Cookieを消しただけでは、盗まれたIDを使った別の端末からのアクセスまでは止められません。サーバー側のセッションを無効にして初めて、そのIDを使えなくできます。
パスワード変更や権限昇格などの重要な状態変化でも、現在のセッションを再認証させたり、既存セッションを無効化したりする設計が必要になることがあります。
安全に扱うためのポイント
- セッションIDはフレームワークの安全な機能を使って生成する。独自に生成する場合は、暗号論的に安全な疑似乱数生成器を使い、十分なエントロピーを確保する。
- ログイン成功時や権限が変わる操作の後は、セッションIDを再発行する。攻撃者が事前に用意したIDを使わせるセッション固定攻撃への対策になる。
- セッションIDをCookieで渡す場合は、HTTPSを使い、原則として
SecureとHttpOnlyを設定する。用途に応じてSameSiteやCSRFトークンも組み合わせる。 - セッションIDをURLのクエリ文字列に含めない。リンク、履歴、アクセスログ、
Refererヘッダーなどを経由して漏れるおそれがある。 - サーバー側のセッションストアは、IDや状態を扱う重要なデータとしてアクセス制御し、不要になった期限切れセッションを削除する。
sessionStorageとは別のもの
名前は似ていますが、ブラウザのsessionStorageはWeb Storage APIの一部で、タブなどの閲覧コンテキストにひも付くクライアント側の保存領域です。
サーバー側でログイン状態を管理するセッションとは別の仕組みであり、HTTPリクエストに自動では送信されません。
参考資料
- RFC 9110: HTTP Semantics
- OWASP: Session Management Cheat Sheet
- RFC 6265: HTTP State Management Mechanism
- HTML Standard: Web storage