코딩기록

Java converter 사용 시 주의해야 할 점 - 회원가입 및 로그인 구현 관련 본문

백엔드/Spring Boot

Java converter 사용 시 주의해야 할 점 - 회원가입 및 로그인 구현 관련

빌럽스 2024. 3. 27. 14:42

 

  • 현재 직장인들을 위한 커뮤니티 개발 팀에서 계정 백엔드 개발을 담당하고 있다.

  • Converter를 적용하여 db에 비밀번호를 저장할 경우 자동으로 BCryptPasswordEncoder를 이용하여 저장되게 하였다.

  • 그런데 converter를 구현한지 얼마 되지 않아, 팀원분께서 두번째 로그인을 시도할 때부터 로그인이 되지 않는다는 노티를 해 주셨다.

  • 원인을 찾아본 결과, Converter 의 문제였다.
    Converter를 적용하여 db에 비밀번호를 저장할 경우 자동으로 BCryptPasswordEncoder를 이용하여 저장되게 하였는데, 그 전에 구현한 기능 중 유저가 로그인 시 해당 로그인 유저의 최근방문시점 및 방문횟수를 업데이트 하도록 구현한 것이 있었다.
    기존에 최근방문시점 및 방문횟수를 아래처럼 jpa가 수정하도록 하였는데, 이경우 모든 컬럼에 대해 update문이 날라가서 User 엔티티의 @convert에 의해 이미 인코딩되어 저장되어 있는 password가 한번더 인코딩되어 저장되는 문제였던 것이다.
  • 해결 방법
  • 첫번째 시도
    최근방문시점 및 방문 횟수를 직접 작성한 쿼리문으로 업데이트하도록 수정했다.
    @Modifying
    @Query(value = "UPDATE users SET number_of_visits = number_of_visits+1 WHERE login_id = :loginId", nativeQuery = true)
    void mIncreaseNumberOfVisitsByLoginId(String loginId);

    @Modifying
    @Query(value = "UPDATE users SET last_visited_at = NOW() WHERE login_id = :loginId", nativeQuery = true)
    void mUpdateLastVisitedAt(String loginId);
  • 문제점: 유저 엔티티 변경하는 모든 경우에 jpa를 사용하지 못하고 쿼리문을 작성해야 해서 부적절했다.


  • 두번째 시도
    User 엔티티의 비밀번호 필드에 updatable = false 를 붙여 비밀번호 수정을 jpa에서 못하게 하고, 유저가 직접 비밀번호 변경을 요청할 때에는 직접 작성한 update 쿼리문을 날리도록 했다.
    @Convert(converter = PasswordEncryptConverter.class)
    @Column(name = "password", nullable = false, updatable = false)
    private String password;

 

  • 문제점: 회원가입 시에는 자동으로 인코딩 되나, 비밀번호 수정 요청에는 직접 백엔드 단에서 BCryptPasswordEncoder로 인코딩하여 db에 넘겨주어야 했다. 즉, 회원가입 시와 비밀번호 수정 요청때 비밀번호를 저장하는 방법이 일관성이 없었다.

  • 세번째 시도(해결)
    일관성 유지할 수 있도록 converter를 없애고, 비밀번호를 저장하는 상황에는 bCryptPasswordEncoder 호출하여 비밀번호 인코딩하도록 수정했다.


  • 느낀 점
    모든 데이터를 일괄적으로 바꾸는 기능을 사용할 경우 이 기능이 미치는 영향을 면밀하게 예측해 보아야 겠다고 생각했다.