Post

MVP 속도전 - RDB로 완성한 EmailAuth 전략

MVP 속도전: RDB로 완성한 EmailAuth 전략


최근 SW성과관리시스템의 MVP 개발을 진행했다. 원래 본 서비스 출시는 2025년 말이었으며, 2026년 전기 졸업과제 관리부터 사용될 예정이었다. 하지만 8월 해커톤 대회에서 투표 기능을 먼저 시험해보고 싶다는 SW 교육센터 측 요청이 있었다. 이에 SW성과관리시스템의 ‘성과 – 투표 & 확인’ 기능을 포함한 MVP 개발을 결정했다. (본 시스템은 정보컴퓨터공학부의 졸업과제 관리와 SW교육센터의 대회 관리로 나뉜다. 졸업과제 관리는 학부 허가가 필요해 MVP가 필요했다.) 백엔드, 프론트엔드, 인프라, 디자인 팀이 여러 차례 회의를 거쳐 MVP 개발 범위를 결정했고 상세 기획을 진행했다.

그러나 SW교육센터에서 요청한 마감 기한이 기말고사 기간과 겹쳐 조금 급하게 개발해야 했다. 개발은 협업이 중요한 만큼 파트별 마감일을 정리했다. 결과적으로 백엔드는 일주일 내 Database 설계, 개발을 끝내기로 했다. 이 중 내가 맡은 역할은 Database 설계와 Spring Security를 활용한 인증 및 인가, 회원가입과 로그인 관련 API 개발, 파일 설정이다.

Database 설계를 하며, ‘인증(EmailAuth)과 관련하여 어떻게 간단하지만 효율적으로 요구사항을 맞출 수 있을까?’ 고민했고, 그 과정과 결과 그리고 느낀점을 남겨보려 한다.


1. 주어진 상황

<요구사항>

  • 부산대 이메일 (@pusan.ac.kr)로만 회원가입 가능
  • 이메일 인증 필요
    • 이메일 인증은 회원가입 시 & 비밀번호 변경 시 사용된다.
    • 이메일 재전송도 가능해야 한다.
  • 아이디 찾기, 비밀번호 변경이 가능해야 한다.

<제한사항>

  • 간단하게 만들기로 결정한 만큼 redis는 사용하지 않는다.
  • 스케줄러를 사용하지 않는다.

위 상황을 정리하면 다음과 같다.

이메일 인증은 회원가입과 비밀번호 변경 시에만 진행한다. 또한 Redis나 스케줄러 없이 최대한 간단하게 구현한다.

<해결해야 하는 상황 & 해결 방안>

  1. 인증코드를 Redis 없이 어디에 보관할까?

    → 다른 DB를 붙이지 않을 계획이라면, 사용하고 있는 RDB에 보관하면 된다고 생각

  2. 스케줄러 없이 인증이 완료된 인증코드를 어떻게 처리할까?

    → 테이블의 컬럼 구성과 삭제 로직으로 해결하자고 생각

2. 해결 방안


a. 테이블 설계

우선 이메일 인증 관련 Member 테이블과 EmailAuth 테이블을 만들었다.

1
2
- Member : id, name, email, password, studentId, roles, isDeleted
- EmailAuth : id, token, email, isCorrected

팀 Convention 상 데이터베이스 설계 시 외래키를 사용하지 않기로 해서 따로 mapping을 진행하지는 않았다.

b. API 목록

로그인 & 회원가입 & 아이디 찾기 & 비밀번호 찾기 관련하여 8개의 API 명세를 작성했다.

image6-1

회원가입 이메일 인증과 비밀번호 변경 이메일 인증 관련 API를 구분한 이유는 같은 메커니즘이지만 서로 다른 책임을 가진 기능이기 때문이다. 하지만 flow는 비슷하기 때문에 회원가입 로직을 위주로 작성하겠다.

c. 회원가입 흐름

1. 이메일 인증 코드 전송

  • 클라이언트로부터 이메일 주소를 받는다.
  • 부산대 도메인인지 검증한다(교내 사용자만 서비스 이용 가능).
  • 인증 코드를 생성하여 전송한다.
  • EmailAuth 테이블에 코드 정보를 저장한다.
    • 해당 이메일이 이미 존재하면 코드를 업데이트(재전송).
    • 존재하지 않으면 새 레코드를 추가(isCorrected = false).

2. 이메일 인증 코드 검증

  • 클라이언트로부터 인증 코드를 받는다.
  • EmailAuth 테이블에서 해당 이메일을 조회한다.
  • 수신한 코드와 저장된 코드를 비교한다.
    • 일치하면 isCorrected 값을 true로 변경
    • 불일치하면 예외를 발생

3. 회원가입 완료

  • isCorrected 값이 true인지 확인한다.
  • 회원가입이 완료되면 해당 EmailAuth 레코드를 Hard Delete한다.
    • 더 이상 사용되지 않는 데이터이므로 즉시 제거함으로써 테이블 크기 증가를 방지

    이렇게 설계한다면, redis를 사용하지 않고 인증코드를 저장할 수 있으며 회원가입 또는 비밀번호 변경이 끝난 후 해당 레코드를 삭제하기 때문에 테이블 크기는 크게 증가하지 않을 것이라고 생각했다.

3. 한계


인증코드를 다룰 때는 일반적으로 RDB를 쓰지 않으며, 만료기한이 있어야 한다. 따라서 이 방법은 실 서비스에서 사용하기 위해서는 다듬어야 할 부분이 많다.

  • 검증 후 삭제 로직 보강
    • 현재는 인증 코드 확인 후 회원가입이 반드시 이어져야만 레코드가 삭제된다.
    • 인증만 완료하고 실제 가입 절차를 마치지 않으면 isCorrected = true 상태로 남아 있어,

      재시도 시 이메일 인증 없이 가입이 가능해진다.

  • 만료 기한 관리
    • 코드 발급 시점에 expires_at을 반드시 설정하고,
    • 애플리케이션 레이어에서 확인 시점에 만료 여부를 검증하도록 수정이 필요하다.

그러나 이 방법을 생각한 이유는 다음과 같은 보호 장치가 있기 때문이다.

  • 로그인 ID가 학교 이메일 하나뿐
    • 부산대 이메일만 가입 가능하며, 중복 발급되지 않는다.
  • 이메일에 유니크 제약
    • RDB 내에서도 중복 가입을 원천 차단한다.
  • MVP 특성
    • 단기간 제공되는 서비스로, 크게 위협이 될 기능을 포함하지 않는다

4. 결론


실 서비스에서는 로그인 로직이 크게 변경될 가능성이 크다. (학교 통합 아이디를 사용할 예정이며, 인프라 담당자가 진행할 것이다.)

이 방법은 시간 제약·제약 사항·요구 사항 속에서 고안한 대안이다. 오랜 고민 끝에 나온 결과다. 테이블 설계 시 다양한 아이디어를 검토했고, 주어진 환경에서 최적의 방안을 찾기 위해 노력했다.

결과는 실 서비스에서 제외될 예정이지만, 그 과정 자체가 충분히 의미 있었다고 생각한다.

This post is licensed under CC BY 4.0 by the author.