콘텐츠로 이동
✍️ 수정가능누구나 고쳐도 됩니다. 고치면 하단 frontmatter의 갱신일·작성자·변경요약을 남겨 주세요.작성 Claude · 2026-06-04 · v12 재편·raw 컴파일·인간화

로그인 개발 명세 (FRD)

요지

JWT 로그인·로그아웃·토큰 재발급을 어떻게 구현하는지 정리한다. 세 역할이 같은 이메일·비밀번호 인증을 쓰고, 통과하면 Access·Refresh 두 토큰을 발급한다. Refresh는 JS가 손대지 못하도록 HttpOnly 쿠키에만 담는다. 계정 상태 전이와 실패 횟수에 따른 잠금은 모두 서버가 책임진다 — 클라이언트를 믿지 않는다는 원칙이다.

상위 PRD (링크 · 변경 시 알림)

기획은 prd(바뀌면 이 문서도 갱신), 회원 도메인(Member/Status/Role)은 member가 단일 기준이다.

기술 접근 · 아키텍처

토큰·세션 정책

토큰 수명과 서명 키 같은 실제 값은 인프라 설정(infra)에 두고, 여기서는 정책의 뼈대만 다룬다.

  • Access / Refresh 2종: Access는 짧게, Refresh는 길게 산다. Refresh는 HttpOnly + Secure + SameSite=Lax 쿠키로만 저장해 JS가 읽지 못하게 막는다.
  • 재발급: Access 만료 인식 즉시 FE가 /api/auth/refresh 호출(Refresh 쿠키 자동 전송) → 신규 Access 쿠키 수신 → 원요청 재시도. Refresh 갱신 실패 시 즉시 로그아웃.
  • CSRF 방어: SameSite 쿠키 + 서버 토큰 검증.
  • "로그인 상태 유지": ON → Refresh 영속 쿠키(자동 로그인), OFF → 세션(메모리/Session Storage)에만 유지.
  • 계정 잠금: 비밀번호 5회 연속 실패 → status=LOCKED. 관리자가 직접 LOCKED 설정도 가능. 상태는 users.status 컬럼으로 관리.

처리흐름

로그인 요청 → BE 이메일/비번 검증
  ├ 일치 + ACTIVE → Access/Refresh 발급 → 200 + 쿠키 → FE /dashboard
  ├ 불일치 → login_fail_count += 1 → 401 (5회 도달 시 status=LOCKED)
  └ 상태 이상 → INACTIVE 403 / LOCKED 423·403 / WITHDRAWN 403
로그아웃 → Refresh 무효화·쿠키 만료·세션(Redis) 삭제 → 204
Access 만료 → FE /api/auth/refresh → 신규 Access 쿠키 → 원요청 재시도

재설정 성공 시 status=ACTIVE + login_fail_count=0 초기화. 로그인 성공 시에도 카운트 0 초기화.

API · 데이터 모델

인증은 로그인·로그아웃·재발급 세 엔드포인트로 끝난다.

동작 엔드포인트 비고
로그인 POST /api/auth/login 성공 200 + 토큰/사용자 정보, 실패 401
로그아웃 POST /api/auth/logout Refresh 무효화(블랙리스트/DB 컬럼)·쿠키 만료·세션 삭제, 204/200
토큰 재발급 POST /api/auth/refresh Refresh 쿠키 검증 → 신규 Access 발급
  • 데이터: Member email(unique)·password·role·status·last_login_at·login_fail_count. 상세 컬럼은 member §2.
  • 상태 전이: ACTIVE --실패5회--> LOCKED, LOCKED --비번재설정--> ACTIVE, INACTIVE --이메일인증--> ACTIVE, WITHDRAWN은 로그인 제한.

예외·검증

미입력·형식 오류 같은 클라이언트 단의 문제는 공용 검증 규칙(V-01~02·05 등)에서 걸러 서버까지 보내지 않는다. 규칙 전체는 회원가입 개발 명세 (FRD)가 기준이다.

서버가 막을 때는 상태에 따라 메시지를 달리한다. 비밀번호가 틀리면 401("이메일 또는 비밀번호가 올바르지 않습니다"), 이메일 인증 전이면 403/INACTIVE, 잠긴 계정이면 423/LOCKED("계정이 잠겼습니다. 비밀번호를 재설정하거나 관리자에게 문의해주세요"), 탈퇴 계정이면 403/WITHDRAWN이다.

로그아웃은 보안이 우선이라, 네트워크가 실패해도 일단 프런트의 로컬 세션부터 비우고 /login으로 보낸다. 보호된 화면은 들어올 때마다 인증을 다시 확인한다.

의존성 · 영향 범위

테스트 계획

공통 케이스·E2E 전략은 qa-playbook을 따른다. 이 기능에서 꼭 볼 것은 로그인 성공·401·계정 상태별 분기, 5회 실패 잠금, refresh 재발급, 그리고 로그아웃 뒤 보호된 화면에 다시 들어갈 때의 인증 재검사다.

행동 분석용 GA 이벤트는 로그인 흐름의 각 단계마다 심어 둔다. 어디서 막히고 어디서 이탈하는지를 보기 위해서다.

단계 이벤트(예)
진입·상호작용 auth_page_view · auth_input_interact · auth_focus_*_field · auth_toggle_password_visibility · auth_toggle_remember_me
제출·결과 auth_submit_login · auth_login_api_call · auth_login_success · auth_login_failure
실패·잠금 auth_client_validation_failure · auth_error_message_view · auth_retry_login · auth_captcha_shown · auth_account_locked_notice
자동/세션 auth_auto_login_success · auth_auto_login_failure · auth_session_expired_redirect
로그아웃 auth_click_logout · auth_logout_success · auth_logout_network_error · auth_protected_route_redirect · auth_session_clear

작업 분해 (이슈 링크)

진행·완료 상태는 status와 GitHub 이슈에서 확인한다. 관련 이슈: Jira BTS-244.