Javaのログイン認証とは?データベースのユーザー情報と照合する流れ|確認問題の回答例
Javaのログイン認証とは?データベースのユーザー情報と照合する流れの確認問題の回答例です。検索結果・認証結果・保存先を分けて確認しましょう。
問題1:DBの行が見つかっただけでは認証成功ではない
ID 1001の行がDBに見つかりました。この時点でLoginUserをセッションへ保存してよいですか。まだ必要な確認と、その担当を答えてください。
まだ保存してはいけません。LoginDaoが行を返した時点で分かるのは、そのIDの利用者が登録されていることです。LoginModelが入力されたパスワードと取得したハッシュを照合し、成功した場合だけLoginUserを返します。その結果を受け取ったLoginServletがセッションへ保存します。
問題2:入力不備はnull、DB障害はSQLException
入力されたIDがabcの場合と、正しいIDでもDBの検索に失敗した場合は、ModelからServletへどのように伝わりますか。両方をnullにしない理由も答えてください。
| 状態 | 今回のコードの動き |
|---|---|
| IDがabc | Integer.parseIntでNumberFormatExceptionになり、Model内でcatchしてnullを返す。DAOは呼ばない。Servletは失敗ページへ案内する。 |
| DBの検索に失敗 | DAOからSQLExceptionが伝わり、Modelもそのまま呼び出し元へ伝える。Servletがcatchして503を返す。 |
DB障害もnullにすると、正しい情報を入力した利用者にも入力ミスの案内を出してしまいます。「照合を完了して認めなかった」と「検索できず判定を完了できなかった」を区別し、どちらの場合もログインは許可しません。
問題3:認証にだけ使う情報をセッションへ持ち込まない
UserAccountをそのままセッションへ保存せず、LoginUserを作って返す理由を説明してください。それぞれが持つ情報も答えてください。
UserAccountはID・名前・パスワードハッシュを持ち、DAOからModelへの受け渡しと照合に使います。LoginUserはID・名前だけを持ち、認証に成功した後の利用者情報として使います。パスワードハッシュを含む検索結果をそのままセッションへ保存しないように、渡す情報を分けています。
問題4:属性名と型の両方をそろえる
保存側がsession.setAttribute("loginUser", loginUser)なのに、取得側を(Integer) session.getAttribute("loginUserId")と書きました。何が起き、どのように直しますか。
今回の例ではloginUserIdという属性を保存していないので、getAttribute(“loginUserId”)はnullを返します。nullをIntegerへキャストしただけではClassCastExceptionにはなりませんが、必要な利用者情報は取得できません。属性名をloginUserに直し、型もLoginUserにそろえます。
有効なsessionを取得・確認した後の修正例
LoginUser loginUser = (LoginUser) session.getAttribute("loginUser");
名前だけをloginUserへ直してIntegerへのキャストを残すと、保存されているのはLoginUserなのでClassCastExceptionになります。また、session自体がnullでないことと、取得したloginUserがnullでないことは、それぞれ確認が必要です。
問題5:先に旧セッションを無効にしているため、以前の状態は残らない
今回のLoginServletで、既にログインしている利用者が誤ったパスワードで再ログインすると、以前のログイン状態は残りますか。処理の順序に沿って説明してください。
LoginServletはModelを呼ぶ前に、既存セッションがあればinvalidate()を実行します。その後、誤ったパスワードでModelからnullが返るので、失敗ページへリダイレクトしてreturnします。新しいセッションへの保存には進まず、以前のログイン状態も使えなくなります。これは今回の例で採用した再ログイン時の方針です。