# AutonetSellCar 개발 계획서 ## 몽골 중고차 수출 플랫폼 (www.autonetsellcar.com) ### 작성일: 2025-12-06 --- ## 1. 프로젝트 개요 ### 서비스 소개 **AutonetSellCar**는 한국 중고차를 몽골 바이어에게 수출하는 B2C/B2B 플랫폼입니다. 카모두(Carmodoo) 딜러 시스템에서 차량 데이터를 자동 수집하여 몽골 바이어에게 제공합니다. ### 타겟 사용자 | 사용자 유형 | 설명 | 인증 방식 | |------------|------|----------| | 몽골 일반 바이어 | 개인 차량 구매자 | 이메일/Facebook/Google | | 몽골 비즈니스 바이어 | 대량 구매/딜러 | Google OAuth + 사업자 인증 | | 중계자 (Agent) | 한-몽 중개인 | 신분증 인증 필수 | | 관리자 | 시스템 관리 | 이메일/비밀번호 + 2FA | --- ## 2. 현재 구현 상태 ### 완료된 기능 - [x] FastAPI Backend 기본 구조 - [x] 차량 목록/상세 API - [x] 기본 이메일/비밀번호 인증 - [x] Next.js Frontend 기본 구조 - [x] 차량 목록/상세 페이지 - [x] SQLite 로컬 개발 환경 - [x] Carmodoo Agent (차량 데이터 수집기) ### 미구현 기능 - [ ] 소셜 로그인 (Facebook, Google OAuth) - [ ] 몽골 SMS OTP 인증 - [ ] 중계자 신분증 인증 - [ ] 메인 히어로 슬라이더 (영화 필름 스타일) - [ ] 관리자 대시보드 - [ ] 배너/슬라이더 관리 기능 --- ## 3. 기술 스택 ### 3.1 Frontend | 기술 | 버전 | 용도 | |------|------|------| | Next.js | 14.1.0 | React 프레임워크 (App Router) | | TypeScript | 5.3+ | 타입 안정성 | | Tailwind CSS | 3.4+ | 스타일링 | | Axios | 1.6+ | HTTP 클라이언트 | | Zustand | 4.5+ | 상태 관리 | | React Hook Form | 7.49+ | 폼 관리 | | Framer Motion | 11.x | 애니메이션 (슬라이더용) | | next-auth | 4.x | 소셜 로그인 통합 | ### 3.2 Backend | 기술 | 버전 | 용도 | |------|------|------| | FastAPI | 0.109+ | Python 웹 프레임워크 | | SQLAlchemy | 2.0+ | ORM | | PostgreSQL | 16 | 프로덕션 DB (Server1) | | SQLite | - | 로컬 개발용 DB | | Redis | 7 | 세션/캐시 (Server1) | | Pydantic | 2.x | 데이터 검증 | | python-jose | - | JWT 토큰 | | passlib | - | 비밀번호 해싱 | | httpx | - | 비동기 HTTP 클라이언트 | | aiofiles | - | 비동기 파일 처리 | ### 3.3 인증 서비스 (외부) | 서비스 | 용도 | 비고 | |--------|------|------| | Facebook OAuth 2.0 | 소셜 로그인 | PKCE 방식 | | Google OAuth 2.0 | 소셜 로그인 | 비즈니스용 | | Twilio / MessageBird | SMS OTP | 몽골 번호 지원 확인 필요 | | AWS S3 / Cloudflare R2 | 이미지 저장 | 선택 | ### 3.4 인프라 | 서버 | IP | 역할 | |------|-----|------| | Server1 | 192.168.0.201 | PostgreSQL, Redis, Nginx Proxy Manager | | Server2 | 192.168.0.202 | AutonetSellCar (Backend:8000, Frontend:3000) | | Server3 | 192.168.0.203 | Grantech.kr, Cylinx.kr | --- ## 4. 인증 시스템 상세 설계 ### 4.0 보안 아키텍처 개요 중고차 거래 플랫폼의 특성상 **보안이 매우 중요**합니다. 고액 거래가 이루어지므로 이중 토큰 전략을 적용합니다. #### 최종 권장 아키텍처 ``` ┌─────────────────────────────────────────────────────────────┐ │ 몽골 중고차 사이트 인증 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ Facebook OAuth │ │ 이메일/비밀번호 │ │ │ │ + PKCE │ │ (대체 수단) │ │ │ └────────┬────────┘ └────────┬────────┘ │ │ │ │ │ │ └──────────┬───────────┘ │ │ ▼ │ │ ┌─────────────────────┐ │ │ │ 자체 JWT 발급 │ │ │ │ (Access + Refresh) │ │ │ └──────────┬──────────┘ │ │ │ │ │ ┌──────────┴──────────┐ │ │ ▼ ▼ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ Access Token │ │ Refresh Token │ │ │ │ (메모리/State) │ │ (HttpOnly Cookie)│ │ │ │ 15분 수명 │ │ 7일 수명 │ │ │ └─────────────────┘ └─────────────────┘ │ │ │ │ + 판매자 등록 시: 휴대폰 인증 추가 │ │ + 고액 거래 시: 2FA 고려 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` #### 이중 토큰 전략 (Dual Token Strategy) ``` ┌─────────────────────────────────────────────────────────┐ │ Access Token │ │ - 수명: 15분 (기본) ~ 1시간 (최대) │ │ - 용도: API 요청 인증 │ │ - 저장: 메모리 (더 안전) 또는 Zustand State │ │ - 특징: 짧은 수명으로 탈취 시 피해 최소화 │ ├─────────────────────────────────────────────────────────┤ │ Refresh Token │ │ - 수명: 7일 (기본) ~ 30일 (최대) │ │ - 용도: Access Token 재발급 │ │ - 저장: HttpOnly Cookie (XSS 방지) │ │ - 특징: JavaScript 접근 불가, CSRF 보호 필요 │ └─────────────────────────────────────────────────────────┘ ``` #### 토큰 갱신 플로우 ``` ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Frontend │ │ Backend │ │ Database │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ │ API 요청 (Access Token 만료) │ │──────────────▶│ │ │ │ │ │ 401 Unauthorized │ │◀──────────────│ │ │ │ │ │ /auth/refresh (Refresh Token in Cookie) │──────────────▶│ │ │ │ 토큰 검증 │ │ │──────────────▶│ │ │◀──────────────│ │ │ │ │ 새 Access Token + 새 Refresh Token │◀──────────────│ │ │ │ │ │ 원래 API 재요청 │ │──────────────▶│ │ └───────────────┴───────────────┘ ``` ### 4.1 인증 방식 목록 #### 1) 이메일/비밀번호 기본 인증 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Frontend │───▶│ Backend │───▶│ Database │ │ Login Form │ │ /auth/login │ │ users │ └─────────────┘ └─────────────┘ └─────────────┘ ``` - bcrypt 해싱 (비밀번호 암호화) - 이중 토큰 (Access + Refresh) 발급 - Access Token: 15분 수명 - Refresh Token: 7일 수명, HttpOnly Cookie 저장 **비밀번호 정책:** - 최소 8자 이상 - 대문자, 소문자, 숫자, 특수문자 포함 권장 - bcrypt cost factor: 12 (보안 강화) #### 2) Facebook OAuth 2.0 + PKCE + JWT ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Frontend │───▶│ Facebook │───▶│ Backend │───▶│ 자체 JWT │ │ FB Button │ │ OAuth+PKCE │ │ /auth/fb/cb │ │ 토큰 발급 │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ ``` - **PKCE (Proof Key for Code Exchange)** 필수 적용 - Facebook 인증 후 → 자체 JWT(Access + Refresh) 발급 - 몽골에서 Facebook 사용률 높음 - 프로필 정보: email, name, profile_picture **PKCE 플로우:** ``` 1. Frontend: code_verifier (랜덤 문자열) 생성 2. Frontend: code_challenge = SHA256(code_verifier) 계산 3. Frontend → Facebook: code_challenge 전송 4. Facebook → Frontend: authorization_code 반환 5. Frontend → Backend: authorization_code + code_verifier 전송 6. Backend → Facebook: code_verifier로 토큰 교환 7. Backend: 자체 JWT(Access + Refresh) 발급 ``` **필요 설정:** ```env FACEBOOK_APP_ID=your_app_id FACEBOOK_APP_SECRET=your_app_secret FACEBOOK_REDIRECT_URI=https://autonetsellcar.com/api/auth/facebook/callback ``` #### 3) Google OAuth 2.0 + JWT ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Frontend │───▶│ Google │───▶│ Backend │───▶│ 자체 JWT │ │ Google Btn │ │ OAuth Server│ │ /auth/google│ │ 토큰 발급 │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ ``` - 비즈니스 바이어/외국인 용 - Google Workspace 계정 연동 가능 - Google 인증 후 → 자체 JWT(Access + Refresh) 발급 **필요 설정:** ```env GOOGLE_CLIENT_ID=your_client_id GOOGLE_CLIENT_SECRET=your_client_secret GOOGLE_REDIRECT_URI=https://autonetsellcar.com/api/auth/google/callback ``` #### 4) 몽골 휴대폰 SMS OTP 인증 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Frontend │───▶│ Backend │───▶│ SMS Gateway │───▶│ User Phone │ │ Phone Input │ │ /auth/sms │ │ Twilio │ │ +976 xxxx │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ ``` - 몽골 휴대폰 번호 형식: +976 XXXX XXXX - OTP 6자리, 유효시간 5분 - Redis에 OTP 임시 저장 **SMS 게이트웨이 옵션:** | 서비스 | 몽골 지원 | 가격 | 비고 | |--------|----------|------|------| | Twilio | O | ~$0.05/SMS | 글로벌 | | MessageBird | O | ~$0.04/SMS | 유럽 기반 | | Vonage | O | ~$0.05/SMS | 글로벌 | | 몽골 로컬 | 확인 필요 | - | 직접 연동 | **필요 설정:** ```env TWILIO_ACCOUNT_SID=your_account_sid TWILIO_AUTH_TOKEN=your_auth_token TWILIO_PHONE_NUMBER=+1234567890 ``` #### 5) 중계자 신분증 인증 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Frontend │───▶│ Backend │───▶│ Admin │ │ ID Upload │ │ /auth/verify│ │ Manual OK │ └─────────────┘ └─────────────┘ └─────────────┘ ``` - 신분증 이미지 업로드 (앞/뒤) - 관리자 수동 승인 - 승인 후 "중계자" 역할 부여 ### 4.2 사용자 역할 (Role) | 역할 | 권한 | 비고 | |------|------|------| | buyer | 차량 조회, 문의하기 | 기본 | | business | buyer + 대량 견적 요청 | 사업자 인증 | | agent | business + 중계 수수료 관리 | 신분증 인증 | | admin | 모든 권한 | 시스템 관리 | ### 4.3 데이터베이스 스키마 (인증 관련) ```sql -- 사용자 테이블 (확장) ALTER TABLE users ADD COLUMN auth_provider VARCHAR(20) DEFAULT 'email'; -- 'email', 'facebook', 'google', 'phone' ALTER TABLE users ADD COLUMN provider_id VARCHAR(100); -- 소셜 로그인 시 provider의 user_id ALTER TABLE users ADD COLUMN phone_number VARCHAR(20); ALTER TABLE users ADD COLUMN phone_verified BOOLEAN DEFAULT FALSE; ALTER TABLE users ADD COLUMN role VARCHAR(20) DEFAULT 'buyer'; -- 'buyer', 'business', 'agent', 'admin' ALTER TABLE users ADD COLUMN id_card_front VARCHAR(500); ALTER TABLE users ADD COLUMN id_card_back VARCHAR(500); ALTER TABLE users ADD COLUMN verification_status VARCHAR(20) DEFAULT 'none'; -- 'none', 'pending', 'approved', 'rejected' -- SMS OTP 테이블 (또는 Redis 사용) CREATE TABLE sms_otps ( id SERIAL PRIMARY KEY, phone_number VARCHAR(20) NOT NULL, otp_code VARCHAR(6) NOT NULL, expires_at TIMESTAMP NOT NULL, is_used BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` --- ## 5. 메인 히어로 슬라이더 설계 ### 5.1 요구사항 - **이미지 크기**: 500x300 픽셀 (중고차 사진) - **애니메이션**: 영화 필름처럼 한 칸씩 연속 슬라이드 - **속도**: 3-5초마다 자동 전환 - **관리자 기능**: 배너 이미지 CRUD ### 5.2 UI/UX 컨셉 ``` ┌────────────────────────────────────────────────────────────────┐ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 🚗 Car1 │ │ 🚗 Car2 │ │ 🚗 Car3 │ │ 🚗 Car4 │ ───────▶ │ │ │ 500x300 │ │ 500x300 │ │ 500x300 │ │ 500x300 │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ Premium Korean Used Cars │ │ Quality vehicles exported to Mongolia at competitive prices │ │ │ │ [ Browse All Cars ] │ └────────────────────────────────────────────────────────────────┘ ``` ### 5.3 기술 구현 #### Frontend 컴포넌트 (FilmStripSlider.tsx) ```typescript // Framer Motion 기반 무한 슬라이드 const FilmStripSlider = ({ images }: { images: BannerImage[] }) => { // 무한 루프를 위한 이미지 복제 const duplicatedImages = [...images, ...images]; return ( {duplicatedImages.map((img, i) => (
{img.title}
))}
); }; ``` ### 5.4 배너 관리 API #### Backend Endpoints | Method | Endpoint | 설명 | |--------|----------|------| | GET | /api/hero-banners | 활성 배너 목록 (Public) | | GET | /api/hero-banners/settings | 슬라이더 설정 | | GET | /api/admin/hero-banners | 모든 배너 (Admin) | | POST | /api/admin/hero-banners | 배너 생성 | | PUT | /api/admin/hero-banners/{id} | 배너 수정 | | DELETE | /api/admin/hero-banners/{id} | 배너 삭제 | | POST | /api/admin/hero-banners/upload | 이미지 업로드 | | PUT | /api/admin/hero-banners/settings | 설정 변경 | #### 데이터베이스 스키마 ```sql -- 히어로 배너 설정 CREATE TABLE hero_banner_settings ( id SERIAL PRIMARY KEY, slide_interval INTEGER DEFAULT 3000, -- ms animation_type VARCHAR(20) DEFAULT 'film-strip', -- 'film-strip', 'fade', 'slide' image_width INTEGER DEFAULT 500, image_height INTEGER DEFAULT 300, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 히어로 배너 이미지 CREATE TABLE hero_banners ( id SERIAL PRIMARY KEY, title_ko VARCHAR(100), title_en VARCHAR(100), title_mn VARCHAR(100), -- 몽골어 image_url VARCHAR(500) NOT NULL, link_url VARCHAR(500), -- 클릭 시 이동 URL (선택) car_id INTEGER REFERENCES cars(id), -- 연결된 차량 (선택) is_active BOOLEAN DEFAULT TRUE, display_order INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` --- ## 6. 관리자 페이지 설계 ### 6.1 관리자 메뉴 구조 ``` /admin ├── /dashboard # 대시보드 (통계, 현황) ├── /hero-banners # 히어로 배너 관리 ├── /cars # 차량 관리 │ ├── /list # 차량 목록 │ ├── /sync # 카모두 동기화 │ └── /makers # 제조사/모델 관리 ├── /users # 사용자 관리 │ ├── /list # 사용자 목록 │ └── /verifications # 신분증 인증 대기 ├── /inquiries # 문의 관리 ├── /settings # 사이트 설정 └── /profile # 관리자 프로필 ``` ### 6.2 대시보드 통계 | 항목 | 설명 | |------|------| | 총 차량 수 | 등록된 차량 수 | | 오늘 방문자 | 일일 방문자 통계 | | 신규 문의 | 미읽음 문의 수 | | 신규 가입 | 오늘 가입자 수 | | 인증 대기 | 신분증 인증 대기 건수 | ### 6.3 Grantech.kr 참고 구조 Grantech.kr에서 참고할 관리자 기능: - 배너 관리 (`/admin/banners`) - 프로젝트 관리 (`/admin/projects`) - 문의 관리 (`/admin/contact`) - 알림 관리 (`/admin/notifications`) --- ## 7. 개발 일정 (작업 순서) ### Phase 1: 메인 히어로 슬라이더 (우선순위 높음) | 작업 | 상세 | 예상 | |------|------|------| | 1-1 | Backend: hero_banners 모델/스키마 생성 | - | | 1-2 | Backend: hero_banners API 구현 | - | | 1-3 | Frontend: FilmStripSlider 컴포넌트 | - | | 1-4 | Frontend: 메인 페이지 히어로 섹션 적용 | - | | 1-5 | Admin: 히어로 배너 관리 페이지 | - | ### Phase 2: 관리자 페이지 기본 | 작업 | 상세 | 예상 | |------|------|------| | 2-1 | Admin: 레이아웃 및 네비게이션 | - | | 2-2 | Admin: 로그인 페이지 | - | | 2-3 | Admin: 대시보드 | - | | 2-4 | Admin: 차량 관리 페이지 | - | ### Phase 3: 소셜 로그인 | 작업 | 상세 | 예상 | |------|------|------| | 3-1 | Facebook OAuth 설정 (Developer Console) | - | | 3-2 | Google OAuth 설정 (Cloud Console) | - | | 3-3 | Backend: OAuth 엔드포인트 구현 | - | | 3-4 | Frontend: 소셜 로그인 버튼 | - | | 3-5 | 사용자 DB 스키마 확장 | - | ### Phase 4: SMS OTP 인증 | 작업 | 상세 | 예상 | |------|------|------| | 4-1 | SMS 게이트웨이 선정 및 계정 생성 | - | | 4-2 | Backend: SMS 발송 서비스 구현 | - | | 4-3 | Backend: OTP 검증 API | - | | 4-4 | Frontend: 휴대폰 인증 UI | - | ### Phase 5: 중계자 인증 | 작업 | 상세 | 예상 | |------|------|------| | 5-1 | Backend: 신분증 업로드 API | - | | 5-2 | Frontend: 신분증 업로드 UI | - | | 5-3 | Admin: 인증 승인 관리 페이지 | - | --- ## 8. 환경 변수 설정 ### Backend (.env) ```env # Database USE_SQLITE=True # False for production DB_HOST=192.168.0.201 DB_PORT=5432 DB_NAME=mongolcar DB_USER=admin DB_PASSWORD=your_password # Redis (Refresh Token 저장, OTP 임시 저장) REDIS_HOST=192.168.0.201 REDIS_PORT=6379 REDIS_PASSWORD=your_password # ============================================ # JWT 이중 토큰 설정 (보안 강화) # ============================================ # Access Token 설정 SECRET_KEY=your-super-secret-key-for-jwt-minimum-32-chars ALGORITHM=HS256 ACCESS_TOKEN_EXPIRE_MINUTES=15 # 15분 (보안 강화) # Refresh Token 설정 REFRESH_SECRET_KEY=your-refresh-secret-key-different-from-access REFRESH_TOKEN_EXPIRE_DAYS=7 # 7일 # 세션 타임아웃 (참고용 - 프론트엔드에서 관리) SESSION_TIMEOUT_MINUTES=30 # ============================================ # 비밀번호 보안 설정 # ============================================ BCRYPT_COST_FACTOR=12 # bcrypt rounds (12 권장, 높을수록 안전) # ============================================ # OAuth 설정 # ============================================ # Facebook OAuth 2.0 + PKCE FACEBOOK_APP_ID= FACEBOOK_APP_SECRET= FACEBOOK_REDIRECT_URI=http://localhost:3000/api/auth/facebook/callback # Google OAuth 2.0 GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= GOOGLE_REDIRECT_URI=http://localhost:3000/api/auth/google/callback # ============================================ # SMS OTP 설정 (Twilio) # ============================================ TWILIO_ACCOUNT_SID= TWILIO_AUTH_TOKEN= TWILIO_PHONE_NUMBER= OTP_EXPIRE_MINUTES=5 # OTP 유효시간 5분 # ============================================ # Carmodoo Agent # ============================================ CARMODOO_USER_ID=01033315258 CARMODOO_PASSWORD=alskfl@1122 AGENT_API_KEY=your_agent_api_key # ============================================ # 파일 업로드 # ============================================ UPLOAD_DIR=./uploads MAX_FILE_SIZE=10485760 # 10MB # ============================================ # 보안 설정 # ============================================ CORS_ORIGINS=http://localhost:3000,https://autonetsellcar.com COOKIE_DOMAIN=localhost # 프로덕션: .autonetsellcar.com COOKIE_SECURE=False # 프로덕션: True (HTTPS 필수) ``` ### Frontend (.env.local) ```env NEXT_PUBLIC_API_URL=http://localhost:8000 # NextAuth (소셜 로그인 사용 시) NEXTAUTH_URL=http://localhost:3000 NEXTAUTH_SECRET=your-nextauth-secret # Facebook FACEBOOK_ID= FACEBOOK_SECRET= # Google GOOGLE_ID= GOOGLE_SECRET= ``` --- ## 9. 파일 구조 (예상) ### Backend 추가 파일 ``` mongolcar/backend/app/ ├── api/ │ ├── auth.py # 확장: OAuth, SMS OTP │ ├── hero_banners.py # 새로 추가 │ └── admin/ │ ├── __init__.py │ ├── dashboard.py │ ├── users.py │ └── verifications.py ├── models/ │ ├── hero_banner.py # 새로 추가 │ └── user.py # 확장 ├── schemas/ │ ├── hero_banner.py # 새로 추가 │ └── user.py # 확장 └── services/ ├── oauth.py # 새로 추가 └── sms.py # 새로 추가 ``` ### Frontend 추가 파일 ``` mongolcar/frontend/src/ ├── app/ │ ├── admin/ │ │ ├── layout.tsx │ │ ├── page.tsx # 대시보드 │ │ ├── login/page.tsx │ │ ├── hero-banners/page.tsx │ │ ├── cars/page.tsx │ │ ├── users/page.tsx │ │ └── verifications/page.tsx │ └── auth/ │ ├── login/page.tsx # 확장 │ └── verify-phone/page.tsx ├── components/ │ ├── FilmStripSlider.tsx # 새로 추가 │ ├── SocialLoginButtons.tsx │ └── admin/ │ ├── Sidebar.tsx │ └── Header.tsx └── lib/ └── auth.ts # NextAuth 설정 ``` --- ## 10. API 엔드포인트 전체 목록 ### 인증 API (이중 토큰 전략) | Method | Endpoint | 설명 | 권한 | |--------|----------|------|------| | POST | /api/auth/register | 회원가입 (Access + Refresh 발급) | Public | | POST | /api/auth/login | 이메일 로그인 (Access + Refresh 발급) | Public | | POST | /api/auth/refresh | Access Token 재발급 (Refresh Cookie 필요) | Public | | POST | /api/auth/logout | 로그아웃 (Refresh Token 무효화) | User | | GET | /api/auth/me | 현재 사용자 정보 | User | | GET | /api/auth/facebook | Facebook OAuth + PKCE 시작 | Public | | POST | /api/auth/facebook/callback | Facebook 콜백 (자체 JWT 발급) | Public | | GET | /api/auth/google | Google OAuth 시작 | Public | | POST | /api/auth/google/callback | Google 콜백 (자체 JWT 발급) | Public | | POST | /api/auth/send-otp | SMS OTP 발송 (Redis 저장) | Public | | POST | /api/auth/verify-otp | SMS OTP 검증 | Public | | POST | /api/auth/upload-id-card | 신분증 업로드 (중계자용) | User | | PUT | /api/auth/change-password | 비밀번호 변경 (bcrypt) | User | ### 히어로 배너 API | Method | Endpoint | 설명 | 권한 | |--------|----------|------|------| | GET | /api/hero-banners | 활성 배너 목록 | Public | | GET | /api/hero-banners/settings | 슬라이더 설정 | Public | | GET | /api/admin/hero-banners | 모든 배너 | Admin | | POST | /api/admin/hero-banners | 배너 생성 | Admin | | PUT | /api/admin/hero-banners/{id} | 배너 수정 | Admin | | DELETE | /api/admin/hero-banners/{id} | 배너 삭제 | Admin | | POST | /api/admin/hero-banners/upload | 이미지 업로드 | Admin | | PUT | /api/admin/hero-banners/settings | 설정 변경 | Admin | ### 관리자 API | Method | Endpoint | 설명 | 권한 | |--------|----------|------|------| | GET | /api/admin/dashboard | 대시보드 통계 | Admin | | GET | /api/admin/users | 사용자 목록 | Admin | | GET | /api/admin/verifications | 인증 대기 목록 | Admin | | PUT | /api/admin/verifications/{id} | 인증 승인/거절 | Admin | --- ## 11. 참고 자료 ### 프로젝트 파일 위치 ``` D:\Workspace\claudeCode\AutonetSellCar\ ├── mongolcar/ │ ├── backend/ # FastAPI 백엔드 │ ├── frontend/ # Next.js 프론트엔드 │ └── agent/ # Carmodoo Agent ├── agent/ # 원본 Agent (백업) ├── Grantech.kr/ # 참고용 (관리자 페이지) └── 문서들 ├── PROGRESS_2025-11-27.md ├── PROGRESS_2025-11-28.md ├── SERVER_INFRASTRUCTURE_PLAN.md └── AUTONETSELLCAR_DEVELOPMENT_PLAN.md (이 파일) ``` ### OAuth 설정 가이드 - Facebook: https://developers.facebook.com/docs/facebook-login/ - Google: https://developers.google.com/identity/protocols/oauth2 ### SMS 게이트웨이 - Twilio: https://www.twilio.com/docs/sms - MessageBird: https://developers.messagebird.com/ --- ## 12. 보안 체크리스트 ### 12.1 인증 보안 - [ ] bcrypt cost factor 12 이상 적용 - [ ] Access Token 수명 15분 이하 - [ ] Refresh Token HttpOnly Cookie 저장 - [ ] PKCE 적용 (Facebook OAuth) - [ ] CSRF 토큰 적용 - [ ] Rate Limiting (로그인 시도 제한) ### 12.2 통신 보안 - [ ] HTTPS 강제 (프로덕션) - [ ] CORS 설정 (허용 도메인만) - [ ] Cookie Secure 플래그 (HTTPS) - [ ] Cookie SameSite=Strict ### 12.3 데이터 보안 - [ ] SQL Injection 방지 (ORM 사용) - [ ] XSS 방지 (React 자동 이스케이프) - [ ] 민감 정보 로깅 금지 - [ ] 환경 변수 Git 제외 --- ## 13. 변경 이력 | 날짜 | 내용 | 작성자 | |------|------|--------| | 2025-12-06 | 최초 작성 | Claude Code | | 2025-12-06 | 이중 토큰 전략 추가 (Access + Refresh Token) | Claude Code | | 2025-12-06 | Facebook OAuth PKCE 상세 플로우 추가 | Claude Code | | 2025-12-06 | 보안 아키텍처 다이어그램 추가 | Claude Code | | 2025-12-06 | bcrypt 비밀번호 정책 추가 | Claude Code | | 2025-12-06 | 보안 체크리스트 추가 | Claude Code | --- *Generated by Claude Code - 2025-12-06*