스프링과 JPA 기반 웹 애플리케이션 개발 #13 회원 가입 패스워드 인코딩
해당 내용은 인프런, 스프링과 JPA 기반 웹 애플리케이션 개발의 강의 내용을 바탕으로 작성된 내용입니다.
강의를 학습하며 요약한 내용을 출처를 표기하고 블로깅 또는 문서로 공개하는 것을 허용합니다 라는 원칙 하에 요약 내용을 공개합니다. 출처는 위에 언급되어있듯, 인프런, 스프링과 JPA 기반 웹 애플리케이션 개발입니다.
제가 학습한 소스코드는 https://github.com/n00nietzsche/jakestudy_webapp 에 지속적으로 업로드 됩니다. 매 커밋 메세지에 강의의 어디 부분까지 진행됐는지 기록해놓겠습니다.
Account
엔티티를 저장할 때 패스워드 인코딩하기PasswordEncoderFactories.createDelegatingPasswordEncoder()
@Configuration
public class AppConfig {
@Bean
// 기본 생성자로 등록하는지 등록 과정 다시한번 살펴보기
public PasswordEncoder passwordEncoder() {
// 사실상 BCryptPasswordEncoder 를 쓰게 된다.
// BCrypt 는 의도적으로 해싱하는데 시간을 조금 걸리게 만든다.
// `.encode()` 메소드를 통해 평문 문자열과 salt를 주어 해싱 문자열을 만들고
// `.matches()` 메소드를 통해 평문과 문자열을 보냈을 때, 보안 인증이 되는지 알 수 있다.
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
PasswordEncoder
타입의 객체 하나를 빈으로 올린다.
...
private final PasswordEncoder passwordEncoder;
private Account saveNewAccount(SignUpForm signUpForm) {
Account account = Account.builder()
.email(signUpForm.getEmail())
.nickname(signUpForm.getNickname())
.password(passwordEncoder.encode(signUpForm.getPassword()))
...
패스워드를 넣을 때, 의존성 주입 받은 PasswordEncoder
를 통해 .encode()
메소드를 한번 돌려준다. 그러면 스프링 시큐리티 내부의 PasswordEncoderFactories.createDelegatingPasswordEncoder()
메소드를 통해 생성된 객체가 주입되어 해당 .encode()
메소드를 수행한다.
여기서 기본 암호화 방식으로 bcrypt
가 쓰이며 salt
는 매번 랜덤으로 들어간다.
String email = "minsu@minsu.co.kr";
String nickname = "minsu";
String password = "12345678";
mockMvc.perform(post("/sign-up")
.param("nickname", nickname)
.param("email", email)
.param("password", password)
.with(csrf())) // CSRF 토큰도 mock 하기
.andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/"));
assertTrue(accountRepository.existsByEmail(email));
assertTrue(accountRepository.existsByNickname(nickname));
Account account = accountRepository.findByEmail(email);
assertNotNull(account);
assertNotEquals(account.getPassword(), password);
올바른 인풋값을 입력하고 회원가입이 됐을 때, 패스워드가 평문과 일치하지 않는 것에 대해 assertNotEquals()
메소드를 통해 확인한다.