Spring Boot + Thymeleaf + DB 想定、ログインができない
前回から引き続き、ログイン機能実装時のエラーの対処の仕方を元に、エラー原因を特定する際の考え方と、実際に特定するための切り分け作業をまとめました。
1. まず押さえる「原因のかたまり」
ログイン失敗は、だいたい次のどれか(または複合)に分けて考えると迷子になりにくいです。
| 区分 | 意味(かみ砕き) |
|---|---|
| ① リクエストが届いていない | URL が違う、404、本番にコードが載っていない、POST がブロックされている、など |
| ② 認証ロジックの前で落ちている | バリデーション、フォームの名前・パスが Controller と合っていない、など |
| ③ DB からユーザーが取れない / 中身がおかしい | メール不一致、SELECT の結果が期待と違う、MyBatis のカラム名マッピングで null になる、など |
| ④ パスワード照合で落ちている | 平文とハッシュの取り違え、BCrypt の matches の引数順、登録時と検証時でエンコーダが違う、など |
| ⑤ 成功しているのに「見た目が失敗」 | セッション未設定、リダイレクト先でまたログインに飛ばされる、キャッシュ、別タブで古い画面、など |
「どの箱に入るか」を先に決めると、ログやブレークポイントの置き場所が決まります。
2. 考え方のコア(デバッグの順番)
-
症状を言語化する
- 「常に失敗する」のか「環境だけ」か(ローカル OK / 本番 NG など)。
- 画面にエラーメッセージは出るか(flash / バリデーション)。
- HTTP のステータスは 200 / 302 / 404 / 500 のどれか。
-
データの流れに沿って一本線で追う
ブラウザ → Controller → Service/Mapper → SQL → 戻り値 → パスワード照合 → セッション → リダイレクト → 次の画面。
「どの段階で期待と違うか」を一つずつ潰す。 -
「null / 空」は最優先で疑う
ユーザーがnull、パスワードハッシュがnull、セッション属性が付いていない、などはログイン失敗の典型原因です。なぜ null か(SQL・マッピング・デプロイ忘れ)を掘ります。 -
一度に変えない
DB をいじりつつコードも変えると原因が追えなくなるので、切り分けが終わるまで変更は小さく・一つずつ。
3. 具体的な切り分け手順(チェックリスト)
以下は 上から順に 試すと楽です。該当しなければ次へ。
Step A — ブラウザ・HTTP の確認
-
ログイン送信後の URL は意図どおりか(
/loginに POST されているか)。 - 開発者ツール → Network で POST の ステータス(302 ならリダイレクト、404/405 はルートやメソッド不一致)。
- 本番のみ失敗する場合:デプロイされたコードにログイン機能が含まれているか(古いビルド・別ブランチを見ていないか)。
Step B — Controller に届いているか
-
ログ出力またはブレークポイントで、
POSTメソッドに メール・パスワードが届いているか(届かないならフォームのname/th:object/methodを確認)。 -
バリデーションエラーで別の分岐に行っていないか(
BindingResultを見る)。
Step C — DB 検索の結果
- 同じメールで DB を直接 SELECT して行が存在するか。
-
アプリから
findByEmail相当の直後で、Userがnullでないか。 -
nullでない場合、パスワード用のフィールド(例:passwordHash)が null でないか。- MyBatis なら カラム名
password_hashと Java のpasswordHashが自動では繋がらないことがあり、SQL でAS passwordHashなど エイリアスが必要なパターンがある。
- MyBatis なら カラム名
Step D — パスワード照合
- 登録時は BCrypt でエンコードした値を DB に保存しているか(平文をそのまま保存していないか)。
-
ログイン時は
encoder.matches(入力の平文, DB のハッシュ)になっているか(平文とハッシュの 順番を間違えない)。 -
登録とログインで 同じ
PasswordEncoder(BCrypt) を使っているか。
Step E — 「認証は通っているのに画面がおかしい」
- 成功時に セッションにログイン情報を入れているか、その キー名が TOP 側のチェックと一致しているか。
-
302 で
/topなどに飛んだあと、別の Controller が/loginにリダイレクトしていないか(未ログイン判定の条件)。
Step F — ログ・例外
- アプリログに スタックトレースが出ていないか(500 は別ルートの問題)。
- SQL ログを一時的に出して、発行された SQL とパラメータが想定どおりか(MyBatis のデバッグ設定など)。
4. よくあるパターンと当たり
| 現象 | 疑うところ |
|---|---|
| ローカルは OK、本番だけ 404 | デプロイ・ルーティング・ビルド対象ブランチ |
| どのユーザーでも必ず失敗 |
passwordHash が常に null(マッピング)、照合コードのバグ |
| 正しいはずのユーザーだけ失敗 | メールの表記揺れ(大文字小文字・空白)、DB のデータ |
| ログイン成功したように見えるがすぐログイン画面 | セッションが効いていない、TOP で未ログイン扱い、Cookie/SameSite(別トピック) |
5. まとめ
ログイン不具合は、(1) HTTP で POST が正しいか、(2) Controller に値が届くか、(3) DB からユーザーとハッシュが取れているか(null に注意)、(4) BCrypt の matches が正しいか、(5) 成功後のセッションとリダイレクト先の整合、の順で切り分けると原因が特定しやすい。