스프링과 JPA 기반 웹 애플리케이션 개발 #33 패스워드 수정 테스트

Jake Seo·2021년 6월 4일
0

스프링과 JPA 기반 웹 애플리케이션 개발 #33 패스워드 수정 테스트

해당 내용은 인프런, 스프링과 JPA 기반 웹 애플리케이션 개발의 강의 내용을 바탕으로 작성된 내용입니다.

강의를 학습하며 요약한 내용을 출처를 표기하고 블로깅 또는 문서로 공개하는 것을 허용합니다 라는 원칙 하에 요약 내용을 공개합니다. 출처는 위에 언급되어있듯, 인프런, 스프링과 JPA 기반 웹 애플리케이션 개발입니다.

제가 학습한 소스코드는 https://github.com/n00nietzsche/jakestudy_webapp 에 지속적으로 업로드 됩니다. 매 커밋 메세지에 강의의 어디 부분까지 진행됐는지 기록해놓겠습니다.


SettingsControllerTest 작성

updatePasswordSuccess 메소드 작성

    @DisplayName("패스워드 수정하기 - 입력값 정상")
    @WithAccount(nickname = "jake")
    @Test
    public void updatePasswordSuccess() throws Exception {
        mockMvc.perform(post("/" + SettingsController.PASSWORD_MAPPING_PATH)
                .param("newPassword", "12345678")
                .param("newPasswordConfirm", "12345678")
                .with(csrf()))
            .andExpect(status().is3xxRedirection())
            .andExpect(redirectedUrl("/" + SettingsController.PASSWORD_MAPPING_PATH))
            .andExpect(flash().attributeExists("message"));

        Account account = accountRepository.findByNickname("jake");
        // 패스워드 검증할 때, 패스워드 인코더로 `.matches()` 메소드 활용해서 인자 앞에는 `rawPassword` 뒤에는 `bcrypt`로 해야함
        // 랜덤한 salt 로 암호화되기 때문에, 암호화된 객체 2개를 비교하거나 그런 방식으로 하면 안됨.
        // 평문과 암호화된 객체 2개가 있어야 패스워드가 올바른지 확인 가능함
        assertTrue(passwordEncoder.matches("12345678", account.getPassword()));
    }

PasswordEncoder를 통해 .encode() 된 패스워드는 어느 경우에도 절대 문자열로 비교하면 안된다. 내부에서 제공하는 .matches() 메소드를 통해 확인해야 한다.

위는 .matches() 메소드에 대한 설명이다. 왜 .matches() 메소드로만 확인해야 하냐면, 같은 패스워드 인코딩 방식이어도 인코딩에 쓰이는 salt는 랜덤하게 들어가기 때문이다.

위 소스코드를 보면 random.nextBytes()라는 부분이 있고 해당 메소드에서 랜덤한 값을 대입하여 랜덤한 salt를 생성한다. 랜덤한 salt를 사용하기 때문에 동일한 문자를 패스워드로 인코딩해도 패스워드 값은 다르게 나올 수 밖에 없다.

암호화된 문자열을 비교하려 하지 말고, .matches() 메소드를 이용하자.

profile
풀스택 웹개발자로 일하고 있는 Jake Seo입니다. 주로 Jake Seo라는 닉네임을 많이 씁니다. 프론트엔드: Javascript, React 백엔드: Spring Framework에 관심이 있습니다.

0개의 댓글