status, page_id, related_pages, last_updated
status
page_id
related_pages
last_updated
stable
A06_Login
2026-07-12
A06_Login — Backend
세션 쿠키 기반 로그인 + OTP 재인증 + 세션/비밀번호 관리 API.
파일 구조
파일
위치
역할
A06_Login_Router.py
A06_Login/A06_Login_Router.py:1-179
인증 API 라우터 (prefix /api/auth)
A06_Login_Schema.py
A06_Login/A06_Login_Schema.py:1-20
요청 검증 Pydantic 모델 3종
API 엔드포인트
엔드포인트
위치
역할
POST /api/auth/login/request
A06_Login/A06_Login_Router.py:51
1차 로그인(이메일+비번). 신규 브라우저/주기 재인증 시 otp_required 반환
POST /api/auth/login/verify
A06_Login/A06_Login_Router.py:113
OTP 검증 후 세션 발급
GET /api/auth/session
A06_Login/A06_Login_Router.py:145
현재 세션 사용자 조회 (id/email/name/role/company_id/is_master)
POST /api/auth/logout
A06_Login/A06_Login_Router.py:160
세션 삭제 + 쿠키 제거
POST /api/auth/password
A06_Login/A06_Login_Router.py:170
비밀번호 변경 (현재 비번 검증, 재인증 필요 반환)
내부 헬퍼
함수
위치
역할
_user_agent(request)
A06_Login/A06_Login_Router.py:40
User-Agent 헤더 추출(최대 1000자)
_send_otp(user, purpose, label)
A06_Login/A06_Login_Router.py:44
OTP 생성·해시 저장·메일 발송
_finish_login(user, agent)
A06_Login/A06_Login_Router.py:87
세션 생성·쿠키 설정·last_login 갱신·로그인 기록
요청 스키마 (Pydantic)
모델
위치
필드
LoginRequest
A06_Login/A06_Login_Schema.py:6
email(EmailStr), password(8~128자)
OtpVerifyRequest
A06_Login/A06_Login_Schema.py:11
email(EmailStr), otp_code(정규식 ^\d{6}$)
PasswordChangeRequest
A06_Login/A06_Login_Schema.py:16
current_password, new_password(8~128자), logout_all(기본 True)
로그인 로직 흐름
login/request: 이메일 조회 → 계정 잠금 확인 → 비밀번호 검증 → 계정 상태 확인(ACTIVE/NO_COMPANY/PENDING만 허용)
OTP 트리거 조건 (둘 중 하나면 OTP 요구):
주기적 재인증: last_email_verified_at이 EMAIL_REVERIFY_DAYS 이전
신규 브라우저: has_known_browser() 미확인
login/verify: OTP 검증 → 소비 → last_email_verified_at 갱신 → _finish_login
_finish_login: 로그인 실패 초기화 → 브라우저 신뢰 등록 → auth_expires_at = NOW() + 3개월 → 세션 생성
보안 정책 (실 코드 기준)
비밀번호 실패 : record_failed_login() 누적, 5회 이상 & ADMIN_EMAIL 설정 시 보안 경고 메일 발송
계정 잠금 : account_locked_until이 미래면 423 반환
로그인 기록 : 모든 시도를 record_login()으로 기록(성공/실패 사유 포함)
의존성 (공통 유틸)
common_util — common_util_auth(세션/OTP/해시), common_util_auth_repository(DB 조회), common_util_email(메일 발송)
인증/세션/OTP 정책 상세 → auth_rbac
config_system — ADMIN_EMAIL, EMAIL_REVERIFY_DAYS
⚠️ 계획서와 실 코드 불일치
auth_rbac 는 계획서 기준(OTP 5분·재시도 3회, 세션 4h/12h, 5회 실패 15분 잠금)으로 기술돼 있으나,
실 코드는 auth_expires_at = NOW() + 3개월 갱신·브라우저 신뢰 기반 OTP·5회 실패 시 관리자 알림 메일 방식.
정책 상세 검증 필요 — 규칙 6(실 코드 우선)에 따라 auth_rbac 갱신 대상.