인증 도메인 Tech Spec. - 100-hours-a-week/5-yeosa-wiki GitHub Wiki

1. 개요 (Overview)

카카오 소셜 로그인을 중심으로 구축된 React 기반의 인증 시스템입니다. 두 개의 핵심 경로를 통해 사용자 인증을 처리합니다:

  • /login : 카카오 소셜 로그인 페이지 - 사용자가 로그인을 시작하는 진입점
  • /auth/kakao/callback: 카카오 로그인 콜백 페이지 - 카카오에서 인증 완료 후 돌아오는 처리 지점

시스템의 핵심 철학은 보안성과 사용자 경험의 균형을 맞추는 것입니다. Access Token은 메모리에 저장하여 XSS 공격을 방지하고, Refresh Token은 세션 스토리지에 저장하여 새로고침 시에도 인증 상태를 유지합니다.


2. 주요 기능 (Core Features)

2.1 카카오 소셜 로그인

  • 카카오 OAuth 2.0 표준을 따르는 인증 플로우 사용자가 별도의 회원가입 과정 없이 카카오 계정으로 즉시 서비스를 이용할 수 있도록 함. 초대 링크를 통한 접근과 일반 로그인을 구분하여 처리하며, 각각에 맞는 적절한 리다이렉션 제공

Kakao Oauth Flowchart

2.2 토큰 관리

이중 토큰 관리 전략

  • Access Token : 5분이라는 짧은 수명을 가지며 메모리에만 저장되어 보안을 강화합니다
  • Refresh Token : 긴 수명을 가지며 세션 스토리지에 저장되어 사용자가 브라우저를 새로고침하거나 탭을 닫았다 다시 열어도 로그인 상태를 유지할 수 있습니다.
  • 자동 갱신 메커니즘 : 사용자가 서비스를 이용하는 동안 토큰 만료로 인한 중단이 발생하지 않습니다. 토큰 갱신 중에는 중복 요청을 방지하는 로직이 있어 시스템의 안정성을 보장합니다.

2.3 인증 상태 관리

Zustand를 활용한 전역 상태 관리를 통해 애플리케이션 전체에서 일관된 인증 상태를 유지합니다. 새로고침 후에도 인증 상태가 자동으로 복구되며, 보호된 라우트에 대한 접근 제어가 체계적으로 이루어집니다.


3. 컴포넌트 구조 (Component Architecture)

3.1 주요 컴포넌트

LoginPage : 로그인 페이지 메인 컴포넌트사용자의 접근 유형을 분석하고 적절한 인증 플로우를 시작합니다. URL 파라미터를 분석하여 일반 로그인, 초대 링크, 보호된 페이지 접근, 세션 만료 등의 상황을 구분하여 처리합니다.

KakaoCallback: 카카오 인증 완료 후의 콜백을 처리하는 전담 컴포넌트입니다. 인가 코드를 받아 서버와 통신하여 토큰을 교환하고, 초대 링크 처리 로직을 포함합니다.

OnboardingUI: 터치 기반의 인터랙티브한 슬라이드쇼를 제공하여 신규 사용자에게 서비스의 핵심 기능을 소개합니다. 스와이프 제스처와 마우스 드래그를 모두 지원하여 다양한 디바이스에서 일관된 경험을 제공합니다.

MovingDotsLoader: 인증 처리 중 사용자에게 시각적 피드백을 제공하는 로딩 컴포넌트입니다.

3.2 컴포넌트 계층 구조

Login Page (/login)
├── OnboardingUI
│   ├── 슬라이드 컨테이너
│   ├── 네비게이션 인디케이터
│   └── 터치/마우스 이벤트 핸들러
└── KakaoLoginButton

Callback Page (/auth/kakao/callback)
├── MovingDotsLoader (로딩 상태)
├── ErrorFallback (에러 상태)
└── 자동 리다이렉션 로직

4. 데이터 및 상태 관리 (Data & State Management)

4.1 핵심 타입 정의

interface User {
    userId: string
    nickname: string
    profileImageURL: string
    cacheTtl: number
}

interface LoginResponse {
    accessToken: string
    refreshToken: string
    refreshTokenExpiresIn: number
    user: User
    code: string
    message: string
}

interface AuthState {
    type: 'normal' | 'invite' | 'protected' | 'expired'
    redirectUrl?: string
    inviteCode?: string
    originalPath?: string
}

4.2 상태 관리 전략

전역 상태 (Zustand Stores)

  • authStore

persist 미들웨어 사용하여 데이터의 지속성을 관리

  • Access Token : 메모리에만 저장
  • 사용자 정보와 Refresh Token : 세션 스토리지에 저장
  • isRefreshing : 동시성 제어를 위한 상태
interface AuthState {
    // Persistent data (sessionStorage)
    refreshToken: string | null
    refreshTokenExpiresIn: number | null
    user: User | null
    isAuthenticated: boolean

    // In Memory data
    accessToken: string | null
    accessTokenExpiresAt: number | null

    // 토큰 갱신 상태 
    isRefreshing: boolean
}

로컬 상태 각 컴포넌트는 자신의 UI 상태만을 관리하며, 인증과 관련된 비즈니스 로직은 전역 상태에 위임.


5. 특화 로직 (Specialized Logic)

5.1 카카오 소셜 로그인 플로우

카카오 로그인은 OAuth 2.0 Authorization Code Grant 플로우를 따릅니다:

1. 사용자가 카카오 로그인 버튼 클릭
   ↓
2. 카카오 인증 서버로 리다이렉트 (state 파라미터에 컨텍스트 정보 포함)
   ↓
3. 사용자가 카카오에서 인증 및 권한 동의
   ↓
4. 인가 코드(authorization code)와 함께 콜백 URL로 리다이렉트
   ↓
5. 클라이언트가 인가 코드를 서버로 전송
   ↓
6. 서버에서 카카오 API를 통해 액세스 토큰 교환
   ↓
7. 사용자 정보 조회 및 로그인 처리 완료
   ↓
8. 적절한 페이지로 최종 리다이렉트

5.2 초대 링크 처리 시스템

초대 링크는 Base64 인코딩된 state 파라미터를 통해 처리됩니다. 이 방식은 URL의 복잡성을 줄이면서도 필요한 정보를 안전하게 전달할 수 있게 해줍니다. 로그인 완료 후 원래 초대된 페이지로 자동 리다이렉트되어 사용자 경험의 연속성을 보장합니다.

초대 데이터 구조

interface InviteData {
    type: 'invite'
    redirectUrl: string
}

5.3 토큰 관리 전략

TokenManager 클래스는 토큰 관리의 복잡성을 캡슐화합니다.

  • 자동 토큰 갱신: API 호출 전에 토큰의 유효성을 검사하고 필요시 자동으로 갱신
  • 중복 요청 방지: 동시에 여러 API가 호출되어도 토큰 갱신은 한 번만 실행
  • 우아한 실패 처리: 갱신 실패 시 사용자를 로그인 페이지로 안전하게 리다이렉트

토큰 수명 관리:

  • Access Token: 5분 (300초) - 짧은 수명으로 보안 강화
  • Refresh Token: 서버에서 설정된 기간 (보통 2주) - 사용자 편의성 고려

5.4 보안 고려사항

  • XSS 공격 방지: Access Token을 메모리에만 저장하여 악성 스크립트가 토큰에 접근할 수 없도록 합니다.
  • CSRF 공격 방지: state 파라미터를 활용하여 요청의 정당성을 검증합니다.
  • 토큰 탈취 대응: 짧은 Access Token 수명과 자동 갱신을 통해 토큰 탈취 시 피해 최소화
  • 세션 관리: 세션 스토리지 사용으로 브라우저 탭 간 세션 격리