前提・実現したいこと
SpringBootをつかってログイン機能を勉強として作っています。
認証はSpringSecurityを使っています。
ログインボタンを押したらユーザーの名前とログインに使用したIDをログイン後の画面に表示したいのですが、Controllerの処理の書き方がよくわからずにいます。
principalを使ったらユーザー名だけは取得できたのですが、ユーザーの全情報を取得できるようにしたいです。
DBにはユーザー情報が1レコード登録してありそれを取り出してControllerで受け渡しをしたいです。
該当のソースコード
LoginController.java
1@Controller 2public class LoginController { 3 4 @Autowired 5 UserForm userForm; 6 7 @Autowired 8 UserService userService; 9 10 @GetMapping({"/", "/login"}) 11 public String loginForm(UserForm userForm, Model model) { 12 13 return "/login"; 14 } 15 16 /* 17 * ログイン認証処理 18 */ 19 @PostMapping("/index") 20 public String loginFormSubmit(@Valid @ModelAttribute UserForm loginUser, 21 BindingResult result, Model model) { 22 23 if(result.hasErrors()) { 24 return "/login"; 25 } 26 27 UserEntity userInfo = userService.loginCheck(loginUser.getUserId(), loginUser.getPassword()); 28 29 if(userInfo == null) { 30 model.addAttribute("error", "error"); 31 32 return "/login"; 33 } 34 setLoginInfo(userInfo); 35 model.addAttribute(loginUser); 36 37 38 return "redirect:/index"; 39 } 40 41 private void setLoginInfo(UserEntity userEntityResult) { 42 43 this.userForm.setUserId(userEntityResult.getUserId()); 44 this.userForm.setPassword(userEntityResult.getPassword()); 45 this.userForm.setUserName(userEntityResult.getUserName()); 46 47 } 48 49 @GetMapping("/index") 50 public String afterLogin(@ModelAttribute UserForm loginUser, Model model) { 51 52 model.addAttribute("loginUser", loginUser); 53 54 return "/index"; 55 } 56 57 58} 59
UserService.java
1@Service 2@Transactional 3public class UserService { 4 5 @Autowired 6 private UserRepository userRepository; 7 8 @Autowired 9 LoginUserDao loginUserDao; 10 11 @Autowired 12 private BCryptPasswordEncoder passwordEncoder; 13 14 public UserEntity create(UserEntity account, String rawPassword) { 15 String encodePassword = passwordEncoder.encode(rawPassword); 16 account.setPassword(encodePassword); 17 18 return userRepository.save(account); 19 } 20 21 public UserEntity loginCheck(String userId, String password) { 22 return loginUserDao.findUser(userId); 23 } 24 25}
LoginUserDao.java
1@Repository 2public class LoginUserDao { 3 4 @Autowired 5 EntityManager em; 6 7 public UserEntity findUser(String userId) { 8 String query = ""; 9 query += "SELECT * "; 10 query += "FROM USERS "; 11 query += "WHERE USER_ID = :userId "; 12 13 return (UserEntity)em.createNativeQuery(query, UserEntity.class).setParameter("userId", userId) 14 .getSingleResult(); 15 } 16} 17
login.html
1<!DOCTYPE html> 2<html xmlns:th="http://thymeleaf.org"> 3<head> 4 <meta charset="UTF-8"> 5 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous"> 6 <link rel="stylesheet" th:href="@{/css/login.css}" /> 7 <script type="text/javascript" th:src="@{/js/login.js}"></script> 8 <script th:src="@{/js/masking_setting.js}"></script> 9 <title>ログイン画面</title> 10</head> 11<body> 12 <div class="contents"> 13 <div class="logo_wrapper"> 14 <img class="logo" th:src="@{/images/logo.jpg}" /> 15 </div> 16 <form th:action="@{/index}" method="post" th:object="${userForm}"> 17 <div class="form-group"> 18 <label for="user_id_form">User ID</label> 19 <input type="text" class="form-control" name="userId" id="user_id_form" th:field="*{userId}" placeholder="ユーザーID"> 20 <span th:if="${#fields.hasErrors('userId')}" th:errors="*{userId}"></span> 21 </div> 22 <div class="form-group"> 23 <label for="password_form">Password</label> 24 <input type="password" class="form-control" name="password" id="password_form" th:field="*{password}" placeholder="パスワード"> 25 <span th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></span> 26 </div> 27 <div class="form-group form-check"> 28 <input type="checkbox" class="form-check-input" id="password_check"> 29 <label class="form-check-label" for="pass_check">パスワードを表示する</label> 30 </div> 31 <button id="login" type="submit" class="btn btn-primary">ログイン</button> 32 </form> 33 </div> 34</body> 35</html>
index.html
1<!DOCTYPE html> 2<html xmlns:th="http://thymeleaf.org"> 3<head> 4 <meta charset="UTF-8"> 5 <title>ログイン後の画面</title> 6</head> 7<body> 8<div th:object="${loginUser}"> 9 <p>ログインユーザーID:<span th:text="*{userId}"></span></p> 10 <p>ログインユーザー名:<span th:text="*{userName}"></span></p> 11</div> 12</body> 13</html>
UserEntity.java
1@Entity 2@Table(name = "USERS") 3public class UserEntity implements UserDetails{ 4 5 /** 6 * 7 */ 8 private static final long serialVersionUID = 1L; 9 10 @Id 11 @Column(name = "USER_ID") 12 @NotEmpty 13 private String userId; 14 15 @Column(name = "USER_NAME") 16 @NotEmpty 17 private String userName; 18 19 @Column(name = "ADMIN_FLG") 20 private int adminFlg; 21 22 @Column(name = "PASSWORD") 23 @NotEmpty 24 private String password; 25 26 public String getUserId() { 27 return userId; 28 } 29 30 public void setUserId(String userId) { 31 this.userId = userId; 32 } 33 34 public String getUserName() { 35 return userName; 36 } 37 38 public void setUserName(String userName) { 39 this.userName = userName; 40 } 41 42 public int getAdminFlg() { 43 return adminFlg; 44 } 45 46 public void setAdminFlg(int adminFlg) { 47 this.adminFlg = adminFlg; 48 } 49 50 public String getPassword() { 51 return password; 52 } 53 54 public void setPassword(String password) { 55 this.password = password; 56 } 57 58 @Override 59 public Collection<? extends GrantedAuthority> getAuthorities() { 60 // TODO 自動生成されたメソッド・スタブ 61 return null; 62 } 63 64 @Override 65 public String getUsername() { 66 // TODO 自動生成されたメソッド・スタブ 67 return null; 68 } 69 70 @Override 71 public boolean isAccountNonExpired() { 72 // TODO 自動生成されたメソッド・スタブ 73 return false; 74 } 75 76 @Override 77 public boolean isAccountNonLocked() { 78 // TODO 自動生成されたメソッド・スタブ 79 return false; 80 } 81 82 @Override 83 public boolean isCredentialsNonExpired() { 84 // TODO 自動生成されたメソッド・スタブ 85 return false; 86 } 87 88 @Override 89 public boolean isEnabled() { 90 // TODO 自動生成されたメソッド・スタブ 91 return false; 92 } 93 94} 95
JpaUserDetailsServiceImpl.java
1@Component 2@Service 3public class JpaUserDetailsServiceImpl implements UserDetailsService { 4 5 //DBからユーザ情報を検索するメソッドを実装したクラス 6 @Autowired 7 private LoginUserDao userDao; 8 9 @Override 10 public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException { 11 12 UserEntity user = userDao.findUser(userId); 13 14 if (user == null) { 15 throw new UsernameNotFoundException("User" + userId + "was not found in the database"); 16 } 17 List<GrantedAuthority> grantList = new ArrayList<GrantedAuthority>(); 18 GrantedAuthority authority = new SimpleGrantedAuthority("USERS"); 19 grantList.add(authority); 20 21 //rawDataのパスワードは渡すことができないので、暗号化 22 BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); 23 24 UserDetails userDetails = (UserDetails)new User(user.getUserName(), encoder.encode(user.getPassword()),grantList); 25 26 return userDetails; 27 } 28}
試したこと
上述した通り、Principalを使うとユーザー名だけは取得できました。
ただそれだけでなく、UserFormにある情報(ユーザーIDとユーザー名の両方)を取得したいです。
@PostMappingだけで完結させればいいかと思ってloginFormSubmit()にいろいろ書いていたのですが、それだとログイン後の画面URLに遷移したときGETがないといけないといったエラーがでてしまったため@GetMappingの処理も書きました。
@ModelAttributeを両方に書けばいくかと思って書いたのですがデバッグするとUserFormがnullになっていました。
上記のような感じで書いてあります。
ログイン先の画面への移行はできたのですが、そもそものuserInfoとしたところがユーザー情報をすべて返すように作ったと思ったのにnullが返ってきています。
dao内の書き方が悪いのでしょうか。
全然わからなくなってしまったため教えていただきたいです。
お手数おかけしますがよろしくお願いします。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/25 12:22