본문으로 건너뛰기
버전: 0.68.0

카카오 로그인 연동 가이드

개요

카카오 로그인은 모바일 앱(iOS, Android) 사용자가 Kakao OAuth 2.0 인가를 통해 우리 서비스에 인증하고, 백엔드가 JWT 액세스/리프레시 토큰을 발급하는 표준 흐름입니다. 이 문서는 모바일 클라이언트, 백엔드(dha-sleep-api), Kakao OAuth 서버 간 상호작용을 한눈에 파악할 수 있도록 시퀀스 다이어그램과 단계별 설명을 제공합니다.

상세 도메인 규칙은 KR Auth 도메인 문서를, 엔드포인트 계약은 KR Auth 엔드포인트를 참고하세요.

전체 로그인 흐름 요약

  1. 모바일 앱이 백엔드 /auth/oauth/kakao 엔드포인트로 인가 URL을 요청합니다.
  2. 백엔드는 state/nonce를 TimeMachine 기준 TTL(10분)로 Redis에 저장하고 인가 URL을 반환합니다.
  3. 모바일 앱은 Kakao SDK 또는 브라우저로 인가 URL을 열어 사용자의 Kakao 인증·동의를 진행합니다.
  4. Kakao 서버는 authorization code와 state를 백엔드 콜백 (/auth/oauth/kakao/callback)으로 전달합니다.
  5. 백엔드는 state 검증 및 Kakao 토큰 교환을 수행한 뒤 Auth Core에 JWT 발급을 위임합니다.
  6. 백엔드는 앱 스킴으로 리다이렉트하면서 JWT 액세스/리프레시 토큰을 전달하거나, 앱 전용 API 응답으로 토큰을 반환합니다.

시퀀스 다이어그램

단계별 상세

1. 인가 URL 초기화 (모바일 → 백엔드)

  • 엔드포인트: GET /auth/oauth/kakao
  • 응답: authorizationUrl, state, expireAt
  • 중요 포인트
    • state/nonce는 TimeMachine 기준 TTL 10분으로 Redis auth:kr:kakao:session:*에 저장합니다.
    • 이 단계가 없으면 클라이언트가 직접 Kakao로 이동하게 되어 state/nonce를 서버가 제어할 수 없으므로 콜백 위·변조, 재전송 공격을 방지하기 어렵습니다.
    • 모바일은 반환된 state를 안전하게 보관 후 Kakao 콜백에서 그대로 전달해야 합니다.

2. Kakao 인증 진행 (모바일 ↔ Kakao)

  • 모바일은 Kakao SDK, 앱 스킴, 또는 WebView로 인가 URL을 열어 사용자의 Kakao 계정 인증과 동의를 받습니다.
  • 인증 완료 후 Kakao는 사전에 등록된 리다이렉트 URI로 code/state를 전달하며, 모바일은 이를 백엔드에 위임합니다.

3. 콜백 처리 및 Kakao 토큰 교환 (모바일 → 백엔드 → Kakao)

  • 엔드포인트: GET /auth/oauth/kakao/callback
  • 백엔드는 다음을 수행합니다.
    1. state 값 검증 및 Redis idempotency 키(auth:kr:kakao:idempotency:{state}) 확인
    2. Kakao 토큰 엔드포인트(https://kauth.kakao.com/oauth/token)와 코드 교환 진행
    3. Kakao 사용자 ID, 프로필 동의 항목을 내부 모델(KakaoUserId)로 변환

4. 내부 사용자 연동 및 JWT 발급 (백엔드 ↔ Auth Core)

  • CompleteKakaoAuthServiceAuth CoreIssueSessionService를 호출해 JWT 액세스/리프레시 토큰을 발급받습니다.
  • 신규 사용자라면 UserProvisionRequiredEvent를 발행하고, 기존 사용자라면 ExternalIdentityLink를 갱신합니다.
  • 발급 결과는 Kakao 로그인 완료 이벤트(KakaoAuthCompletedEvent)와 함께 다운스트림 도메인으로 전파됩니다.

5. 최종 응답 및 이동 (백엔드 → 모바일)

  • 기본 시나리오: 302 리다이렉트로 앱 스킴(app://auth/callback?kakao=true&jwtAccessToken=...)에 JWT 토큰을 전달합니다.
  • 대체 시나리오: 모바일이 폴링/딥링크를 사용할 수 없는 경우 JSON 응답으로 액세스/리프레시 토큰을 반환합니다.
  • 모바일은 JWT를 안전한 저장소(Keychain, Keystore 등)에 저장하고 이후 API 호출 시 Authorization: Bearer 헤더에 포함합니다.

요청/응답 체크리스트

단계요청자핵심 헤더/파라미터성공 시 결과
인가 URL 요청Mobile → BackendUser-Agent, X-Platform, country=KRstate/nonce, authorizationUrl, expireAt
Kakao 인증Mobile ↔ KakaoOAuth 표준 파라미터 (response_type=code, client_id)Authorization Code, state
콜백 처리Mobile → Backendcode, state, (선택) lang, appVersionKakao 토큰 교환, 외부 ID 링크
JWT 발급Backend → AuthCorekakaoUserId, provider='kakao'JWT accessToken, refreshToken
최종 리다이렉트Backend → MobileLocation: app://...jwtAccessToken=...모바일이 JWT 저장 후 후속 호출

보안 및 운영 고려사항

  1. State/Nonce 검증: 모든 콜백에서 state가 일치하는지 확인하고, 만료 또는 불일치 시 도메인 예외(KakaoStateMismatchError)를 반환합니다.
  2. Idempotency: 동일한 콜백이 반복될 경우 Redis idempotency 키로 재처리를 차단합니다.
  3. TimeMachine 사용: 모든 만료 시각 계산과 감사 로그는 TimeMachine에서 제공하는 권한 있는 시각을 사용합니다.
  4. 토큰 저장소: 모바일은 JWT를 안전한 저장소(Keychain/Keystore)에 저장하고, 탈옥·루팅 탐지 및 무결성 검사를 권장합니다.
  5. 모니터링: auth_kakao_login_latency_seconds, auth_kakao_login_failure_total 지표를 수집하고 Alert 기준을 설정합니다.
  6. Feature Flag: Kakao OAuth 장애 시 feature.auth.kakao를 비활성화하여 폴백 로그인 경로를 안내합니다.

참고 문서