webアプリケーションを k3s 環境へ移行した際に セッション管理が問題となり ログインできない事象があったので セッションについて勉強してみた
❓ そもそもセッションとは
いろいろ文献があったけど Oracleさんの記事が一番しっくりきましたので紹介します
セッションを利用することで ユーザーの状況を追跡することができる。本来ユーザーの情報は保持していないステートレスな状態が多く、セッションを使うことでこれらの情報を保持し追跡可能にする。
Oracleさんの言葉をそのまま引用
セッションとは、ある期間中に同じクライアントから出される一連の関連性のあるブラウザ リクエストのこと。
👀 セッションの仕組み
クライアントサイド(ブラウザ) と サーバサイド(WebApplication) 通信方式はHTTP通信を使う
通常HTTP 通信には セッションを維持する仕組みは存在しないが、クライアントとサーバサイドで SESSIONID
を連携することで セッションを維持している。
連携の仕方は主に2種類
- Cookie
- リクエストパラメータ
❤️ Session の ライフサイクルはどうなっているのか
セッションのライフサイクルにおいて リクエスト ~ レスポンスは以下の様になっている
TERASOLUNA Server Framework for Java より参照
生成や利用に関する制御
Spring Security は処理の中で セッションのライフサイクルを管理している様子
- always
- Spring Security の処理で セッションを使わないケースでも常にセッションを生成する
- ifRequired (デフォルト)
- セッションが存在しない場合で オブジェクトにセッションを格納するタイミングでセッションを生成する
- never
- すでにセッションが生成されている場合にセッションを利用する
- セッションが存在していない場合、セッションの生成および利用を行わない
- stateless
- セッションの有無に関係なく セッションの生成および利用を行わない
セッション破棄が行われるタイミング
- ログアウトを実行したタイミング
- ログイン認証が成功した時
- セッション固定化攻撃を防ぐために ログイン前と後でセッションIDを変更している
- セッションタイムアウト
- ユーザーが一定期間セッション利用対象のページでアクションがない場合に破棄される
❓ Session管理はなぜ Redis でよくやられているのか
-
高速なアクセスが求められるセッションデータと、メモリベースのRedisは相性が良い
- セッションはWebリクエストごとに頻繁に読み書きされるため、低レイテンシかつ高スループットなストレージが求められる
- Redisはメモリ上で動作し、Diskや通常のRDBMSと比較してI/Oオーバーヘッドが極めて小さい
- → ディスク < CPU < メモリの順でI/O速度が速く、セッション管理に適している
-
セッションは「一時的」なデータであり、揮発性のRedisと用途がマッチする
- セッションは、一定期間のリクエスト間で一時的に関連情報を保持するための仕組み(例:ログイン状態、ユーザーIDなど)
- セッションは一定時間アクセスがなければ破棄されるべきものであり、永続性はそこまで求められない
- Redisの揮発性(TTL付きキーやメモリ破棄)と、この一時性の要求がうまくマッチする
-
RedisはTTLを自然に使えるので、セッションの有効期限管理と自動削除が簡単
ものすごく参考にさせていただいた記事