UserDetailsImplを作成する
※ユーザー情報を提供するインタフェースの実装
public class UserDetailsImpl implements UserDetails {
private static final long serialVersionUID = 1L;
private String email;
private String password;
private Collection<GrantedAuthority> authorities;
public UserDetailsImpl(String email, String password, Collection<GrantedAuthority> authorities) {
this.email = email;
this.password = password;
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return email;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
メソッド | 戻り値の設定 | 内容 |
---|---|---|
Collection extends GrantedAuthority> getAuthorities() | コンストラクタで設定した値 | 権限リストを返す |
String getUsername() | コンストラクタで設定した値 | ユーザー名を返す |
boolean isAccountNonExpired() | 常に true とする | アカウントの有効期限の判定 |
boolean isAccountNonLocked() | 常に true とする | アカウントのロック状態の判定 |
boolean isCredentialsNonExpired() | 常に true とする | 資格情報の有効期限の判定 |
boolean isEnabled() | 常に true とする | 有効なユーザーであるかの判定 |
UserDetailsServiceImplを作成する
※ユーザー情報をDBから取得するインタフェースの実装
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
JdbcTemplate jdbcTemplate;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
try {
String sql = "SELECT * FROM members WHERE email = ?";
Map<String, Object> map = jdbcTemplate.queryForMap(sql, email);
String password = (String) map.get("password");
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority((String) map.get("authority")));
return new UserDetailsImpl(email, password, authorities);
} catch (Exception e) {
throw new UsernameNotFoundException("user not found.", e);
}
}
}
Security Configを修正する
※インメモリからDB判定に変更
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.inMemoryAuthentication().passwordEncoder(passwordEncoder()).withUser("user")
// .password(passwordEncoder().encode("test")).roles("USER");
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
※認証情報を返すように設定
.formLogin(form -> form.loginProcessingUrl("/login")
.successHandler((request, response, authentication) -> {
Object principal = authentication.getPrincipal();
String authority = authentication.getAuthorities().isEmpty() ? "":authentication.getAuthorities().iterator().next().getAuthority();
Map<String, String> data = new HashMap<>();
if (principal instanceof UserDetails) {
UserDetails userDetails = (UserDetails) principal;
data.put("email", userDetails.getUsername());
data.put("authority", authority);
}
response.setStatus(HttpStatus.OK.value());
response.setContentType("application/json;charset=UTF-8");
new ObjectMapper().writeValue(response.getOutputStream(), data);
})
取得したログイン情報の権限によって遷移先を変更する
const login = async () => {
try {
const response = await axios.post(BASE_URL + '/login', {
username: memberInfo.email,
password: memberInfo.password,
}, {
headers: {
'Content-type': 'application/x-www-form-urlencoded'
}
});
if (response.status === 200) {
console.log("Login success:", response);
//権限で遷移先判定
if (response.data.role === 'ADMIN') {
//管理者ページへ遷移
router.push('/admin')
} else {
//マイページへ遷移
router.push('/myPage')
}
}
} catch (error) {
//ログイン失敗時エラー
console.error("Login failed:", error);
}
}