2026.09.08

Memory Calendar 개발(3) - User 도메인과 회원가입 구현

1. 이번 작업의 목표

지난 작업에서는 PostgreSQL을 연결하고 Flyway로 초기 스키마를 구성했다.

이번에는 사용자를 저장할 User 도메인을 만들고, 이메일 기반 회원가입과 이메일 중복 확인 API를 구현했다. 잘못된 요청과 중복 이메일을 처리하기 위한 공통 예외 응답도 함께 구성했다.

2. User 도메인 구성

User는 MVP에 필요한 정보를 중심으로 구성했다.

  • id: 사용자 식별자
  • email: 회원가입과 로그인에 사용할 이메일
  • password: 해시 처리한 비밀번호
  • name: 사용자 이름
  • createdAt, updatedAt: 생성·수정 시각

초기에는 사용자 권한을 구분할 필요가 없어 role 필드는 추가하지 않았다. 관리자 등 별도 권한이 필요해지는 시점에 확장할 예정이다.

여러 Entity에서 사용하는 생성·수정 시각은 BaseEntity로 분리하고 JPA Auditing을 적용했다. 각 기능에서 시간을 직접 설정하는 중복을 줄이기 위한 구성이다.

사용자 조회와 이메일 중복 확인에는 Spring Data JPA Repository의 다음 메서드를 사용했다.

Optional<User> findByEmail(String email);

boolean existsByEmail(String email);

이메일을 기준으로 사용자를 찾거나, 이미 등록된 이메일인지 확인할 수 있도록 했다.

3. 회원가입과 비밀번호 처리

회원가입 API는 POST /api/auth/signup으로 구현했다.

요청값을 검증하고 이메일 중복 여부를 확인한 뒤, 비밀번호를 해시 처리해 User를 저장한다. 가입에 성공하면 201 Created를 반환한다.

비밀번호는 원문 그대로 저장하지 않도록 BCrypt를 사용했다. Spring Security의 PasswordEncoder를 다음과 같이 등록했다.

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

회원가입에서는 이 Encoder로 처리한 값을 저장하고, 응답에는 비밀번호를 포함하지 않았다. 이후 로그인에서도 같은 Encoder를 사용해 입력한 비밀번호와 저장된 값을 비교할 예정이다.

4. 이메일 중복 확인과 예외 처리

회원가입 전에 이메일 사용 가능 여부를 확인할 수 있도록 별도 API를 추가했다.

GET /api/auth/check-email?email=test@example.com

정상적인 조회 요청에는 200 OK와 함께 available 값을 반환한다. 사용 가능한 이메일이면 true, 이미 등록된 이메일이면 false다.

이 API는 사용자가 가입 전에 확인할 수 있도록 제공하는 기능이다. 실제 회원가입 요청에서도 이메일 중복 여부를 다시 검사한다. 사전 확인 이후 다른 가입 요청으로 해당 이메일이 등록될 수 있기 때문이다.

회원가입 시 중복 이메일이거나 요청값이 잘못된 경우에는 공통 예외 처리 구조를 통해 응답하도록 했다. 오류 응답은 상태, 메시지, 오류 코드, 관련 필드를 같은 형식으로 제공하도록 구성했다.

구현 중에는 이메일 중복 확인의 요청 파라미터 검증 실패가 500으로 반환되는 문제가 있었다. 기존 Handler에서 처리하던 예외와 다른 HandlerMethodValidationException이 발생했기 때문이다. 해당 예외 처리를 추가해 잘못된 입력은 400으로 응답하도록 수정했다.

(참고 : https://shblog.shhome.synology.me/sunghyun/posts/29)

5. 적용 결과

신규 회원가입의 201 Created 응답과 DB 저장, 비밀번호의 BCrypt 처리를 확인했다. 중복 이메일 가입 시 예외 응답과 이메일 사용 가능 여부 조회, 잘못된 이메일 형식의 400 응답도 확인했다.

이번 작업으로 사용자 정보를 저장하고 회원가입 요청을 처리하는 기반을 마련했다.

다음에는 이메일과 비밀번호로 로그인하고, JWT Access Token을 발급하는 기능을 구현한다.