회원가입 기능 트러블슈팅 : 탈퇴한 사용자 예외처리 및 UserDetails 관련 이슈

coldrice99·2024년 11월 4일
0
post-thumbnail

문제 상황

회원 탈퇴 기능을 소프트 삭제 방식으로 구현하기 위해, MemberStatus Enum 클래스를 추가하여 멤버의 상태를 ACTIVE 또는 DELETED로 구분했습니다. 이 후, 이미 회원 탈퇴한 사용자가 재가입하려는 경우 예외처리를 위해 회원가입 API에서 UserDetails 객체를 사용하여 멤버의 상태를 검증하려고 했습니다.

if (userDetails.getMemberStatus().equals(MemberStatus.DELETED)) {
    throw new MemberException("이미 탈퇴한 사용자입니다.");
}

하지만 회원가입 API에서 UserDetailsImpl 객체를 이용해 상태를 확인하려는 과정에서 403 Forbidden 에러가 발생했고, 회원 상태 정보를 가져오려는 userDetails.getMemberStatus()에서 null 포인터 예외가 발생했습니다.


문제 해결을 위한 과정과 시행착오

  1. UserDetailsImpl 객체의 문제 추적:

    • 처음에는 MemberStatusMember 클래스에서 초기화되지 않거나 UserDetailsImpl 클래스에서 상태를 제대로 받지 못해 userDetails.getMemberStatus()가 null이 되는 것으로 추정했습니다.
    • UserDetailsImpl 클래스의 메서드를 여러 차례 수정하고 디버깅했지만, 변화가 없었습니다.
  2. permitAll() 설정 확인:

    • 결국 WebSecurityConfig의 설정을 재점검했습니다. 아래와 같이 회원가입과 로그인 경로permitAll()로 설정되어 인증 없이 접근 가능하도록 되어 있었습니다.
      http.authorizeHttpRequests((authorizeHttpRequests) ->
              authorizeHttpRequests
                      .requestMatchers("/api/auth/**").permitAll() // 회원가입과 로그인 경로 인증 없이 접근 허용
                      .anyRequest().authenticated() // 그 외 경로 인증 요구
      );
    • permitAll() 설정된 경로에서는 인증을 요구하지 않기 때문에 Spring Security가 UserDetails 객체를 생성하지 않습니다. 이로 인해 UserDetailsImpl의 객체가 null이었고, userDetails.getMemberStatus() 호출 시 null 포인터 예외가 발생했던 것입니다.
  3. 최종 해결 방안:

    • UserDetails 객체 없이 MemberStatus를 확인하기 위해, 회원가입 시에는 단순히 중복된 이메일이 있는지 확인하는 방식으로 탈퇴한 회원의 재가입을 막기로 했습니다.
    • 중복된 이메일이 있거나 탈퇴한 회원일 경우, "중복된 사용자 혹은 탈퇴한 회원입니다"라는 메시지로 예외를 처리하였습니다.

추가 학습: permitAll() 설정과 UserDetails 객체 생성의 관계

이번 문제를 통해 Spring Security에서 permitAll() 설정이 된 경로에서는 인증이 필요하지 않아 UserDetails 객체가 null로 처리된다는 점을 알게 되었습니다. 인증 없이 접근 가능한 경로에서는 SecurityContext에 사용자 정보가 설정되지 않으므로, 인증 객체가 생성되지 않습니다. 따라서 회원가입, 로그인과 같은 인증이 필요 없는 경로에서는 UserDetails가 null임을 염두에 두어야 합니다.


결론

단순히 회원 상태를 검증하려는 의도로 UserDetails를 참조했지만, 인증 절차가 생략된 경로에서는 UserDetails 객체가 생성되지 않는다는 점을 미처 고려하지 못했습니다. 이번 경험을 통해 Spring Security의 설정이 어떻게 SecurityContextUserDetails 생성에 영향을 미치는지 이해하게 되었으며, 앞으로는 인증이 필요 없는 경로에서 UserDetails 접근을 시도하지 않도록 주의해야겠습니다.


https://github.com/KimLeeParkJiChoi/spang-eats.git

profile
서두르지 않으나 쉬지 않고

0개의 댓글