TIL

TIL) JPA 비밀번호 암호화

tmddnr3503 2024. 11. 14. 22:04

1. JPA에서 비밀번호를 하는 어노테이션 @Converter

 JPA에서 비밀번호를 암호화 할 때, 암호화하는 Entity의 비밀번호에 @Converter어노테이션을 작성합니다. 이때, 비밀번호를 암호화하는 클래스를 PasswordEncoder라고 한다면 다음과 같은 코드가 작성됩니다.

@Getter
@Entity
@Table(name = "users")
public class Users extends BaseEntity {

  @Convert(converter = PasswordEncoder.class)
  @NotBlank(message = "비밀번호는 필수 입력값입니다.")
  @Length(min = 4, message = "비밀번호는 최소 4자입니다.")
  private String password;

}

 

@NotBlank와 @Length는 각각 공백이 불가능한 조건과 길이가 최소 4여야한다는 조건입니다. 

 

2. 비밀번호를 암호화하는 클래스

 비밀번호를 암호화하는 클래스에는 @Component 어노테이션과 @Converter어노 테이션을 작성합니다. 그 후 AttribteConverter 인터페이스를 implements합니다.

@Converter
@Component
public class PasswordEncoder implements AttributeConverter<String, String> {

  public String encoder(String rawPassword){
    return BCrypt.withDefaults().hashToString(BCrypt.MIN_COST, rawPassword.toCharArray());
  }

  public boolean matches(String rawPassword, String encodedPassword){
    BCrypt.Result result = BCrypt.verifyer().verify(rawPassword.toCharArray(), encodedPassword);
    return result.verified;
  }

  @Override
  public String convertToDatabaseColumn(String password) {
    return encoder(password);
  }

  @Override
  public String convertToEntityAttribute(String password) {
    return password;
  }

}

 

AttributeConverter<String, String>에서 앞 String은 엔티티에서 비밀번호의 타입입니다. 뒤의 String은 데이터 베이스에서의 비밀번호 타입입니다. VarChar는 String으로 매치됩니다. 그 후 convertToDatabaseColumn과 convertToEntityAttribute를 오버라이드해줍니다. 각 메서드의 의미는 다음과 같습니다.

  • convertToDatabaseColumn : 엔티티 -> 데이터 베이스로 저장될 때 실행하는 메서드입니다.
  • convertToEntityAttribute : 데이터 베이스 -> 엔티티로 반환 할 때, 사용하는 메서드입니다.

이때, encoder 메서드로 암호화를 해주고, 비밀번호의 일치여부는 matches 메서드로 진행합니다.

 

3. 실재 로그인에서의 사용

 로그인에서 비밀번호를 일치하는지 메서드로 작성하였고 그 코드는 다음과 같습니다.

private Long checkUserEmailPassword(String email, String password) {
  Users user = findUserByEmailOrThrow(email);
  if(!passwordEncoder.matches(password, user.getPassword())){
    throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "비밀번호가 틀렸습니다.");
  }
  return user.getId();
}

 

현재 입력한 비밀번호와 데이터베이스에 저장되어있는 비밀번호를 matches 를 이용하여 비교합니다.

 

4. 내일 구현해야하는 것

  • 댓글 기능 구현 및 과제 제출