ログイン中のユーザー情報のアップデートとセッションの中身の更新
詰まった内容
- 独自のログインページを実装した際、ユーザーのトップ画面でログインしたユーザーの名前をセッション上から取得し表示するようにした。
- 別のページからユーザーの名前を変更すると、DBのみ更新され画面上の名前を変わらなかった。
- 一度ログアウトして再度ログインし直すことで正しく表示されるので、DB上は変更できているが、ログイン中のセッション内の情報が更新できていない。
ユーザー情報の更新の際、セッション内の情報も一緒に更新が必要
この状態の解決にハマったので、備忘録として記録しておきます。
結論
@AuthenticationPrincipalアノテーションを使う
- このアノテーションでPrincipal内の情報をgetしたりsetしたりできる。
- コントローラ上で認証したセッション情報の更新を行う。アップデート処理のサービスクラスやMapperに関しては変更不要。
- SecurityContextHolderクラス内のUsernamePasswordAuthenticationTokenの中身(認証されたセッション情報が格納されている)を更新できればOK!(詳しい内部構造はよくわかってません(^_^;))
/*
* ユーザー情報変更
*/
@PostMapping("/user/user_info/edit/update")
public String userUpdate(@ModelAttribute @Validated UserEdit userEdit, BindingResult result, Model model,@AuthenticationPrincipal UserForm userForm) {
//受けとったリクエストの入力チェック
if (result.hasErrors()) {
model.addAttribute("edit_user", userEdit);
return "user/user_info_edit";//エラー時は自画面遷移
}
//受け取ったオブジェクトを引数にDBのアップデート処理を実行
userDisplayService.updateUserInfo(userEdit);
//principalに更新したオブジェクトのユーザーネームをセットする
userForm.setPenName(userEdit.getPenName());
//setAuthenticationメソッドでUsernamePasswordAuthnticaionTolkenの中身の認証したセッション情報を更新する
SecurityContext auth = SecurityContextHolder.getContext();
auth.setAuthentication(new UsernamePasswordAuthenticationToken(userForm,userForm.getPenName(), userForm.getAuthorities()));
//ユーザーページへリダイレクト
return "redirect:/user/user_page";
}
- auth.setAuthentication(new UsernamePasswordAuthenticationToken(userForm,userForm.getPenName(), userForm.getAuthorities()));最後のこの部分で、引数がUserFormのオブジェクトを入れておかないと、更新後のユーザーネーム以外nullになってしまう。オブジェクトだけ入れようとしてもエラーになるので上記のような記述となった。まぁ正常に動くのでOK。。。
いろいろ調べたけど、同じような処理をしている記事が見つけられなくて苦労しました。
こんな実装あんましないのかな?
← Go home