Skip to content

Latest commit

 

History

History
170 lines (137 loc) · 5.48 KB

File metadata and controls

170 lines (137 loc) · 5.48 KB

판매자 인증 가이드

📋 개요

Picake 플랫폼의 판매자 인증 시스템은 웹 애플리케이션 환경에서 동작하도록 설계되었습니다. localStorage를 사용한 토큰 관리와 자동 로그인 상태 복원 기능을 제공합니다.

🎯 주요 특징

  • localStorage 기반 토큰 저장: 브라우저 localStorage에 토큰 저장
  • 헤더 기반 토큰 전송: Authorization 헤더에 Bearer 토큰 포함
  • 자동 로그인 상태 복원: 새로고침 시 /me API로 자동 복원
  • 자동 리다이렉트: 401 에러 시 로그인 페이지로 자동 이동

🔄 전체 인증 플로우

1. 로그인 플로우 (웹 앱 → 백엔드)

sequenceDiagram
    participant U as User
    participant F as Frontend
    participant B as Backend
    participant DB as Database

    U->>F: 로그인 정보 입력<br/>(userId, password)
    F->>B: POST /v1/consumer/auth/login<br/>{ userId, password }

    Note over B: 1. 입력 검증 (DTO)
    B->>DB: User 조회 (userId)
    DB-->>B: 사용자 정보

    alt 계정 없음
        B-->>F: 400 - 계정 없음
    else 계정 존재
        B->>B: 비밀번호 검증 (bcrypt)
        alt 비밀번호 틀림
            B-->>F: 401 - 인증 실패
        else 비밀번호 맞음
            alt 휴대폰 미인증
                B-->>F: 400 - 휴대폰 인증 필요
            else 휴대폰 인증 완료
                B->>B: JWT 토큰 생성<br/>(sub: userId, type: ACCESS, 90일)
                B->>DB: lastLoginAt 업데이트
                B-->>F: { accessToken, refreshToken }

                F->>F: localStorage에<br/>토큰 저장
                F->>F: Zustand store 업데이트<br/>(isAuthenticated = true)
                F->>F: 홈 페이지로 이동<br/>(returnUrl 있으면 해당 페이지)
                F-->>U: 로그인 완료
            end
        end
    end
Loading

2. API 요청 플로우 (웹 앱 → 백엔드)

sequenceDiagram
    participant F as Frontend
    participant B as Backend
    participant DB as Database

    F->>F: API 요청 준비
    F->>F: localStorage에서<br/>accessToken 조회
    F->>B: GET /v1/seller/stores<br/>Authorization: Bearer {token}

    Note over B: 1. CORS 검증
    Note over B: 2. @Auth 데코레이터 확인
    Note over B: 3. AuthGuard 실행

    B->>B: JwtStrategy.jwtFromRequest()<br/>Authorization 헤더에서<br/>Bearer 토큰 추출

    alt 토큰 없음
        B-->>F: 401 - ACCESS_TOKEN_MISSING
    else 토큰 존재
        B->>B: JWT 서명 검증<br/>(JWT_SECRET)
        alt 서명 오류
            B-->>F: 401 - ACCESS_TOKEN_INVALID
        else 서명 유효
            B->>B: 토큰 만료 시간 확인
            alt 토큰 만료
                B-->>F: 401 - ACCESS_TOKEN_EXPIRED
            else 토큰 유효
                B->>B: JwtStrategy.validate()<br/>토큰 타입 확인 (ACCESS)
                B->>DB: User 조회 (sub: userId)<br/>최신 role, isActive 확인

                alt 계정 없음/비활성화
                    B-->>F: 401 - ACCOUNT_NOT_FOUND/INACTIVE
                else 계정 유효
                    B->>B: AuthGuard.handleRequest()<br/>역할 검증 (SELLER 권한 확인)
                    B->>B: Controller 실행
                    B->>DB: 비즈니스 로직 처리
                    DB-->>B: 데이터 반환
                    B-->>F: 200 - 성공 응답
                end
            end
        end
    end
Loading

3. 새로고침 시 로그인 유지 플로우

sequenceDiagram
    participant U as User
    participant F as Frontend
    participant B as Backend
    participant DB as Database

    U->>F: 페이지 새로고침

    F->>F: AuthInitializerProvider 마운트
    F->>F: localStorage에서<br/>토큰 확인

    alt 토큰 존재
        F->>B: GET /v1/consumer/auth/me<br/>Authorization: Bearer {token}

        Note over B: JWT 검증 과정 동일
        B->>DB: User 조회
        DB-->>B: 사용자 정보

        alt 토큰 유효
            B-->>F: { accessToken, user }
            F->>F: Zustand store에<br/>로그인 상태 저장<br/>(isAuthenticated = true)
            F->>F: isInitialized = true
            F-->>U: 로그인 상태 유지
        else 토큰 무효
            B-->>F: 401 에러
            F->>F: localStorage에서<br/>토큰 제거
            F->>F: Zustand store 초기화<br/>(isAuthenticated = false)
            F->>F: 로그인 페이지로 리다이렉트
        end
    else 토큰 없음
        F->>F: Zustand store 초기화<br/>(isAuthenticated = false)
        F->>F: isInitialized = true
        F-->>U: 로그아웃 상태 유지
    end
Loading

4. 401 에러 처리 플로우

sequenceDiagram
    participant F as Frontend
    participant B as Backend

    F->>B: API 요청<br/>Authorization: Bearer {token}

    alt 토큰 만료/무효
        B-->>F: 401 - ACCESS_TOKEN_INVALID<br/>{ message: "[ACCESS_TOKEN_INVALID] ..." }

        F->>F: Axios 응답 인터셉터<br/>401 에러 감지
        F->>F: localStorage에서<br/>토큰 제거
        F->>F: 현재 URL을 returnUrl로 저장
        F->>F: 로그인 페이지로 리다이렉트<br/>?returnUrl={현재URL}
    end
Loading

5. 로그아웃 플로우

sequenceDiagram
    participant U as User
    participant F as Frontend

    U->>F: 로그아웃 버튼 클릭
    F->>F: localStorage에서<br/>토큰 제거
    F->>F: Zustand store 초기화<br/>(isAuthenticated = false)
    F->>F: 로그인 페이지로 이동
Loading