Picake 플랫폼의 판매자 인증 시스템은 웹 애플리케이션 환경에서 동작하도록 설계되었습니다. localStorage를 사용한 토큰 관리와 자동 로그인 상태 복원 기능을 제공합니다.
- localStorage 기반 토큰 저장: 브라우저 localStorage에 토큰 저장
- 헤더 기반 토큰 전송: Authorization 헤더에 Bearer 토큰 포함
- 자동 로그인 상태 복원: 새로고침 시
/meAPI로 자동 복원 - 자동 리다이렉트: 401 에러 시 로그인 페이지로 자동 이동
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
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
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
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
sequenceDiagram
participant U as User
participant F as Frontend
U->>F: 로그아웃 버튼 클릭
F->>F: localStorage에서<br/>토큰 제거
F->>F: Zustand store 초기화<br/>(isAuthenticated = false)
F->>F: 로그인 페이지로 이동