728x90
SMALL
0️⃣ 출발점 — 사용자 액션
사용자
└─ LoginViewController
└─ 카카오 로그인 버튼 탭
1️⃣ LoginViewController
역할
- UI 이벤트 처리
- “카카오로 로그인하겠다”는 의도만 전달
- 인증 로직은 절대 모름
authViewModel.login(
provider: .kakao,
from: self
)
LoginViewController
⬇️
AuthViewModel
2️⃣ AuthViewModel
역할
- View ↔ Service 중계
- Auth 상태 관찰 (onAuthStateChanged)
- 에러 전달
authService.login(
with: .kakao,
from: presentationContext,
completion: ...
)
AuthViewModel
⬇️
AuthService
3️⃣ AuthService (🔥 핵심 분기 지점)
역할
- “어떤 소셜 로그인인지” 판단
- 각 소셜 SDK Handler로 위임
- 로그인 전체 플로우의 진입점
case .kakao:
kakaoHandler.login { result in
// Kakao SDK 결과 처리
}
AuthService
⬇️
KakaoAuthHandler
4️⃣ KakaoAuthHandler (SDK 전담)
역할
- Kakao SDK와 직접 통신
- accessToken 획득
- UI Thread에서만 실행됨
KakaoAuthHandler
├─ UserApi.isKakaoTalkLoginAvailable()
│ ├─ YES → loginWithKakaoTalk()
│ └─ NO → loginWithKakaoAccount()
결과
- ✅ 성공 → accessToken
- ❌ 실패 → Kakao SDK Error
KakaoAuthHandler
⬇️ (accessToken)
AuthService
⭐️ 5️⃣ SceneDelegate (중간에 끼어드는 숨은 주인공)
여기서 중요한 개념이 하나 있음.
🔥 왜 SceneDelegate가 필요할까?
카카오톡 로그인은 이런 흐름이야:
앱 → 카카오톡 앱 실행 → 인증 → 다시 우리 앱으로 돌아옴
👉 이 “다시 돌아올 때” iOS는 URL Scheme으로 앱을 깨움
👉 그걸 받는 곳이 바로 SceneDelegate
SceneDelegate 코드의 역할
func scene(
_ scene: UIScene,
openURLContexts URLContexts: Set<UIOpenURLContext>
)
실제 흐름
KakaoTalk 앱
⬇️ (URL Scheme)
SceneDelegate
if AuthApi.isKakaoTalkLoginUrl(url) {
AuthController.handleOpenUrl(url: url)
return // ⭐️ 이 return 이 핵심
}
이 코드의 의미
| 코드 | 의미 |
| isKakaoTalkLoginUrl | 이 URL이 카카오 로그인 콜백인지 검사 |
| handleOpenUrl | Kakao SDK에게 “로그인 계속 진행해라” 전달 |
| return | ❗️ 앱의 다른 딥링크 로직으로 넘어가지 않게 차단 |
📌 이게 없으면
- 카카오 로그인 중간에 끊김
- 앱으로 돌아오자마자 로그인 취소됨
- “카카오톡이 안 열린다” 같은 현상 발생
6️⃣ AuthService → SocialAuthCoordinator
Kakao SDK가 accessToken을 얻으면:
AuthService
⬇️
SocialAuthCoordinator
역할
- “이제 Firebase 인증으로 넘어간다”는 경계선
- SDK와 Firebase를 완전히 분리
try await socialAuthCoordinator.signIn(
with: accessToken,
provider: .kakao
)
7️⃣ SocialAuthCoordinator (🔥 설계의 핵심)
역할
- 소셜 로그인 전체 오케스트레이션
- 순서 보장
- 책임 분리
내부 흐름
SocialAuthCoordinator
├─ validate(provider)
├─ FirebaseFunctionsService.requestCustomToken()
└─ FirebaseAuthService.signIn(withCustomToken)
8️⃣ FirebaseFunctionsService
역할
- Firebase Cloud Functions 호출 전담
- region 지정 (asia-northeast3)
FirebaseFunctionsService
⬇️
Cloud Function (socialLogin)
9️⃣ FirebaseAuthService
역할
- Firebase Auth SDK 래핑
- Custom Token으로 로그인
Auth.auth().signIn(withCustomToken: token)
FirebaseAuthService
⬇️
Firebase Auth
🔟 Auth 상태 변경 → 화면 전환
Firebase Auth
⬇️
AuthService.observeAuthState
⬇️
AuthViewModel.onAuthStateChanged
⬇️
RootCoordinator / Scene 전환
🧠 전체 흐름 한 장 요약
LoginViewController
⬇️
AuthViewModel
⬇️
AuthService
⬇️
KakaoAuthHandler
⬇️
[카카오톡 앱]
⬇️
SceneDelegate (openURLContexts)
⬇️
Kakao SDK resume
⬇️
AuthService
⬇️
SocialAuthCoordinator
⬇️
FirebaseFunctionsService
⬇️
Cloud Functions (socialLogin)
⬇️
FirebaseAuthService
⬇️
Firebase Auth
⬇️
AuthState Changed
⬇️
홈 화면728x90
LIST