[Spring] Encoded password does not look like BCrypt 에러 해결

susu·2023년 2월 24일
0

원인

비밀번호를 암호화하지 않은 상태에서 비교하려고 해서 발생

...
if (!passwordEncoder.matches(loginRequestDto.getPassword(), member.getPassword())) {
            throw new BadCredentialsException("비밀번호가 일치하지 않습니다.");
        }
...

요청으로 들어온 비밀번호를 DB에 저장된 비밀번호와 비교하기 위해 작성한 코드의 일부이다.
그러나 비교가 이루어지지 않아 비밀번호 불일치에 대한 에러가 던져졌다.

해결

처음 회원가입 시에 비밀번호를 암호화해서 DB에 저장하도록 했다.

/* signup API 중 일부 */

...
String encodedPassword = passwordEncoder.encode(signupRequestDto.getPassword());

Member member = Member.builder()
        .email(signupRequestDto.getEmail())
        .nickname(signupRequestDto.getNickname())
        .password(encodedPassword)
        .picture(signupRequestDto.getPicture())
        .build();
memberRepository.save(member);
...

BCryptPasswordEncoder의 matches 메소드 작동 방식은 암호화되어 저장된 비밀번호의 해시 함수를 풀어 요청으로 들어온 비밀번호화 비교하는 것 같았다.
따라서 암호화가 되어 있지 않으면 비교가 불가능해서 에러가 발생했던 것.

트리비아

Spring Security 5.3.3에서 공식 지원하는 PasswordEncoder 구현 클래스들은 다음과 같다.

  • BcryptPasswordEncoder : Bcrypt 해시 함수를 사용하여 비밀번호 암호화
  • Argon2PasswordEncoder : Argon2 해시 함수를 사용하여 비밀번호 암호화
  • Pbkdf2PasswordEncoder : Pbkdf2 해시 함수를 사용하여 비밀번호 암호화
  • SCryptPasswordEncoder : SCrypt 해시 함수를 사용하여 비밀번호 암호화

🚨 커스텀 에러 처리

현재는 HttpStatus로 에러 코드를 찍어주고, ApiResponse에 에러 코드와 메세지를 담아 리턴하는 방식으로 진행하고 있음.

  1. 서비스 단에서 에러를 throw 후, 컨트롤러 단에서 try-catch로 받아서 처리하는 방법
    실제로 로그인 요청에 대해 유효하지 않은 아이디나 비밀번호에 대한 처리를 1번 방식으로 했다.
  2. @ExceptionHandler를 이용한 처리
    스프링 어노테이션을 이용하는 방법. 잘 정리된 글이 있어서 참고하면 될 것 같다.
    🔗 @ExceptionHandler를 통한 예외처리
profile
블로그 이사했습니다 ✈ https://jennairlines.tistory.com

0개의 댓글