Spring Framework-17
🗄 이번엔 인메모리 방식이 아닌 DB에서 유저를 가져와 인증해봅시다!
CustomUserDetailServiceImpl 추가
Spring Security에서는 UserDetailService를 이용하여 유저를 조회합니다. 우리는 이를 구현하는 클래스를 만듭니다. 우리의 username은 email이므로 userMapper가 파라미터로 들어온 email로 유저를 조회하여 반환할 수 있도록 만듭니다.
@Service
@RequiredArgsConstructor
public class CustomUserDetailServiceImpl implements UserDetailsService {
private final UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return userMapper.findByEmail(s);
}
}
UserVO 수정
UserDetailService가 반환하는 클래스는 UserDetails입니다. 따라서 UserVO가 이를 구현하는 클래스로 수정합니다. UserDetails는 반드시 권한을 가져야합니다. 따라서 일단 ROLE_USER를 넣어 반환하겠습니다.
@Data
public class UserVO implements UserDetails {
private int id;
private String name;
private String password;
private String email;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
}
/*
* Spring Security의 username을 반환
*/
@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;
}
}
SecurityConfig 수정
우리는 이제 인메모리 방식이 아닌 커스텀된 UserDetailService를 사용해 유저를 조회합니다. Spring Security는 반드시 PasswordEncoder를 사용해야해 이를 생성하고 반환하는 메소드를 @Bean으로 만들어줍니다. 여기서 PasswordEncoderFactories.createDelegatingPasswordEncoder()는 기본적으로 BCRYPT 인코딩입니다딩
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
UserService 수정
비밀번호를 확인하는 메소드는 필요가 없으므로 주석처리하고, 유저의 정보를 저장할 때 비밀번호를 인코딩하여 저장할 수 있도록 수정합니다.
public interface UserService {
public void save(UserVO userVO);
public boolean checkEmailDuplication(String email);
// public boolean checkPassword(String email, String password);
public UserVO findByEmail(String email);
}
@RequiredArgsConstructor
@Service
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
private final PasswordEncoder passwordEncoder;
@Override
public void save(UserVO userVO) {
userVO.setPassword(passwordEncoder.encode(userVO.getPassword()));
userMapper.save(userVO);
}
@Override
public boolean checkEmailDuplication(String email) {
return userMapper.checkEmailDuplication(email)==0;
}
// @Override
// public boolean checkPassword(String email, String password) {
// return password.equals(userMapper.findByEmail(email).getPassword());
// }
@Override
public UserVO findByEmail(String email) {
return userMapper.findByEmail(email);
}
}
DB 수정
인코딩한 비밀번호는 길어서 user 테이블의 password의 길이를 늘려줍니다. 그리고 이미 있는 user는 모두 삭제해야 하므로 저장되있던 데이터를 모두 삭제합니다.
alter table user modify password varchar(100);
delete from file;
delete from post;
delete from user;
테스트
Author And Source
이 문제에 관하여(Spring Framework-17), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dbghwns11/Spring-Security-17저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)