ログアウト実装の前に確認したこと
Spring Boot + Thymeleaf + セッションでログアウトを入れる前に、自分の頭の中を整理したメモです。
要件や、実装方法を決める上で必要だと感じた知識も合わせてメモとして残しています。
今回の要件として満たしたいこと
- 「ログアウト」ボタンを押したらログアウトする(セッションをやめる)
- 確認メッセージは不要
- ログアウト後はログイン画面(
/login)にリダイレクトする
ヘッダーの出し分け(自分が決めた表)
| ヘッダー | 画面のイメージ |
|---|---|
| ボタンなし | ログイン画面 |
| 「ログイン」 | 新規登録画面 |
| 「ログアウト」 | TOP、あとから増える profile / skill 系など |
未実装の画面は、ルートと Controller ができたら同じ考え方でヘッダーを合わせればよい、という整理。
ログアウト用 URL と Controller のイメージ
- 例として
POST /logoutのような 専用の URL を用意する - その URL に来たら Controller のメソッドが動く
- 中身はだいたい
session.invalidate()(セッション無効化)→redirect:/login
invalidate … いまのブラウザ用セッションを まるごと終了する。ログイン時に入れた loginUserName みたいな 一時メモをまとめて消したいときに向く。
removeAttribute … セッションの 箱は残したまま、名前付きの値を1つだけ消す。ログアウト全体としては invalidate の方が分かりやすい、という理解でメモしておいた。
セッションに入っている「項目」とは
- DB の本体そのものではなく、このブラウザのためにサーバーが一時的に覚えている名前付きのデータ
- いまのプロジェクトだと
loginUserNameが典型例 - ログアウトと同時に消えた方が自然、という感覚で
invalidateに寄せた
なぜログアウトは POST にすることが多いか
- GET は「読む」寄りの約束で、状態を変える操作は POST に寄せる、という整理がある
-
GET の URL はリンクや
<img src>で踏まれうるので、うっかり・悪意でログアウトされやすい。POST はフォーム送信が主で、少しマシ - ブックマークで毎回ログアウトみたいな事故も起きにくい
本番では CSRF トークンもセットで話が出る、くらいは頭の片隅に置いておく。
CSRF(シーサーフ)
・プロジェクトに Spring Security を入れていて CSRF 有効なら、POST のフォームにトークンが必要になることがある。いま Security をどうしているか一度確認しておくと、実装で詰まりにくい。
・CSRF トークン(サーバーが毎回違う秘密の値をフォームに埋め込み、POST のときだけ検証する)で、「そのサイトの正規フォームから送られた POST だけ受け付ける」
Controller を画面の数だけ増やさない
-
invalidate+ リダイレクトの本体は プロジェクト内のどこか1か所だけ(新しいLogoutControllerにしても、既存のLoginControllerに1メソッド足すだけでもよい) - profile 用・skill 用の Controller ごとに同じログアウト処理を書く必要はない
- ヘッダーの「ログアウト」は どの画面からも同じ
POST /logoutを指せばよい
「ヘッダー状態を Model で渡す」か「テンプレートだけで決める」か(判断メモ)
Model で渡す
各画面の GET の Controller が、headerAction のような値を Model に載せる。テンプレートは表示だけ。仕様がはっきりしていて、MVC の流れを追いやすい。載せ忘れには注意。
テンプレートだけ
layout.html で URL とセッションの有無などから分岐。ルールを 1ファイルに集約できる。画面が増えても Controller に同じ1行を増やしにくい反面、HTML にロジックが溜まる。
迷ったら まず Model で実装 → ルールが増えたらテンプレート集約を検討、とメモ。
新規 Java ファイルは必須か
-
LogoutController.javaを新規に作るのは好み。必須ではない -
LoginControllerにPOST /logoutを1つ足すだけでもよい - それ以外は
layout.html・common.css・各.htmlの編集がセットになりがち
実装前に一瞬だけ確認しておくリスト
- Spring Security / CSRF を有効にしているか(有効なら POST フォームにトークンが要ることがある)
-
セッションに載せている属性名の一覧(今は
loginUserNameだけか) -
動作確認のパターンを3〜5個メモ(ログイン → TOP でログアウト →
/login、など)
用語ミニ辞典(自分向け)
| 用語 | ざっくり |
|---|---|
| POST | 状態を変える操作に使いやすい HTTP メソッド |
| リダイレクト | 別の URL を開き直させる応答 |
| Controller | URL と Java メソッドを結びつける部品 |
| Model | そのリクエストでテンプレートに渡すデータの入れ物 |
| セッション | ブラウザごとのサーバー側の一時メモ |
| invalidate | セッションをまるごと終了 |
まとめ
ログアウトの本体は1か所の POST でセッションを終わらせて /login へ。ヘッダーは表どおり出し分け。設計の細部は Model かテンプレートかは後からでも切り替え可能、というメモで止めておく。