💡 PasswordEncoder
- 주로 사용자의 비밀번호를 안전하게 저장하고 검증하기 위한 Spring Security의 인터페이스이다. 구현체들은 다양한 해시 알고리즘을 사용하여 비밀번호를 저장하고, 비교할 수 있도록 도와준다.
- 일반적으로 BCryptPasswordEncoder를 사용하는 것이 권장된다. BCrypt는 해시 함수 중 하나로, 단방향 암호화를 제공하여 비밀번호를 안전하게 저장할 수 있다.
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class SignUpRequest {
private String email;
private String name;
private String password;
public User toEntity(PasswordEncoder passwordEncoder) {
this.password = passwordEncoder.encode(this.password);
return User.builder()
.email(email)
.name(name)
.password(password)
.authority(ROLE_USER)
.build();
}
}
사용자가 회원가입 시 입력한 비밀번호를 BCryptPasswordEncoder를 사용하여 안전하게 저장한다. 그리고 로그인 시에는 입력된 비밀번호를 같은 알고리즘으로 해싱하여 저장된 해시값과 비교한다.

💡 AuthenticationProvider
- supports 메서드를 통해 주어진 Authentication 객체를 지원하는지 여부를 판단한 후 authenticate 메서드를 호출한다.
- 지원하는 경우에는 authenticate 메서드를 호출하여 실제로 사용자를 인증한다. 인증에 성공하면 Authentication 객체를 반환한다.
- authenticate 메서드 내에서 UserDetailsService 클래스의 loadUserByUsername 메서드를 호출하여 입력한 아이디에 해당하는 사용자 정보를 조회하고 UserDetails를 반환한다.
( 존재하지 않을 경우 UserNotFoundException이 발생한다. )- 이후 matches 메서드를 통해 입력한 비밀번호를 해시화하여 UserDetails의 Credentials( 해시된 비밀번호 )과 비교하여 사용자 인증을 진행한다.
( 일치하지 않을 경우 BadCredentialsException이 발생한다. )
@Component
@RequiredArgsConstructor
public class JwtAuthenticationProvider implements AuthenticationProvider {
private final PrincipalDetailsService principalDetailsService;
private final PasswordEncoder passwordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
UserDetails userDetails = principalDetailsService.loadUserByUsername(username);
if (passwordEncoder.matches(password, userDetails.getPassword())) {
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
} else {
throw new SecurityException(SecurityExceptionCode.USER_NOT_FOUND);
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}