728x90
SMALL
🔑 결론 한 줄
Firebase Functions 연동 → Custom Token 파싱 → signIn(withCustomToken:) 는
AuthService 안에 직접 쓰지 말고,
“공용 컴포넌트”로 분리하는 게 정답이다.
1️⃣ 지금 정확히 짚은 문제의 본질
의문을 구조로 풀어보면 이거야 👇
Kakao 로그인
├─ KakaoAuthHandler → accessToken
└─ (공통 단계)
├─ Firebase Functions 호출
├─ Custom Token 파싱
└─ Firebase signIn
Naver 로그인
├─ NaverAuthHandler → accessToken
└─ (공통 단계)
├─ Firebase Functions 호출
├─ Custom Token 파싱
└─ Firebase signIn
👉 이 아래 단계는 완전히 동일
👉 provider만 다를 뿐, 흐름은 100% 같다
“이걸 AuthService 안에 박아두면,
네이버 붙일 때 코드가 중복될 것 같은데?”
정확하다.
2️⃣ 선택지 정리 (그리고 왜 하나만 정답인지)
❌ 선택지 A: AuthService 안에 전부 작성
final class AuthService {
func loginWithKakao() {
// accessToken
// functions 호출
// signIn
}
func loginWithNaver() {
// accessToken
// functions 호출
// signIn
}
}
문제점
- Kakao / Naver 로직이 부분 중복
- Functions URL 하드코딩 중복
- 테스트 어려움
- AuthService가 너무 비대해짐
👉 실무에서 가장 먼저 리팩토링 대상
❌ 선택지 B: AuthService extension으로 분리
extension AuthService {
func exchangeCustomToken(...) { ... }
}
이건 구조만 나눈 것이지,
책임 분리는 아님.
👉 “코드 위치만 다른 AuthService”
✅ 선택지 C (정답): 공용 컴포넌트로 분리
📌 구조 그림
AuthService
├─ KakaoAuthHandler → accessToken
├─ NaverAuthHandler → accessToken (예정)
└─ SocialAuthCoordinator (공용)
├─ Firebase Functions 호출
├─ Custom Token 파싱
└─ Firebase signIn
👉 이게 정답 구조
✅ 이 설계의 “근거”
이건 임의 설계가 아니라 아래 원칙에 딱 맞아.
- SRP (단일 책임 원칙)
- Clean Architecture – UseCase 분리
- Coordinator 패턴
- Firebase 공식 가이드: Custom Token 로그인은 클라이언트 공용 흐름
실무에서도:
- Kakao / Naver / Apple / Google
- 모두 accessToken까지만 다르고
- Firebase 로그인 파이프라인은 하나다
SocialAuthCoordinator가 필요한가?
이유부터 명확히 하자면:
- 네이버 / 카카오는
→ 각 SDK에서 accessToken을 얻는 방식은 다르지만 - Firebase Auth + Functions로 넘기는 흐름은
→ 완전히 동일
즉 역할이 이렇게 나뉘어야 깔끔해 👇
| 책임 | 담당 |
| 네이버 SDK 로그인 | NaverAuthProvider |
| 카카오 SDK 로그인 | KakaoAuthProvider |
| accessToken → Firebase 인증 | SocialAuthCoordinator |
| 앱 전체 인증 흐름 | AuthService |
👉 그래서 SocialAuthCoordinator는 반드시 필요한 추상화야.
SocialTokenProviding 새로 만들어야 할까?
❌ 결론: “새로 만들 필요 없음”
✅ 정답: 기존 KakaoAuthProviding의 개념을 일반화해서 이름만 바꾸자
왜냐하면
네이버 / 카카오의 공통점은 딱 이거 하나야:
accessToken을 발급한다
그래서 프로토콜의 본질은 이미 정해져 있어.
🔁 리네이밍 추천
기존 KakaoAuthProviding → 이렇게 변경
protocol SocialTokenProviding {
func fetchAccessToken() async throws -> String
}
final class KakaoAuthProvider: SocialTokenProviding { ... }
final class NaverAuthProvider: SocialTokenProviding { ... }
SocialLoginProvider enum에 apple / google 있어도 되나?
🔥 이게 핵심 질문인데, 결론은 이거야
지금은 써도 된다
단, Coordinator 레벨에서는 “사용 범위”를 제한하자
왜 써도 되냐면
- 이 enum의 의미는 “Firebase에 전달할 provider 타입”
- Firebase 관점에서는
→ apple / google / kakao / naver 전부 같은 레벨의 provider임
enum SocialLoginProvider {
case apple
case google
case kakao
case naver
}
이 자체는 문제 없음 ❌❌
그럼 “네이버·카카오만 필요”한데 왜 괜찮냐?
👉 의존 방향을 제한하면 됨
❌ 잘못된 사용
SocialAuthCoordinator.signIn(
accessToken: token,
provider: .apple // ❌ 책임 침범
)
✅ 올바른 사용
SocialAuthCoordinator.signIn(
accessToken: token,
provider: .kakao
)
그리고 Coordinator 내부에서만 제한해도 충분해 👇
guard provider == .kakao || provider == .naver else {
throw AuthError.unsupportedProvider
}
즉,
- enum은 확장 가능하게 두고
- Coordinator가 허용 범위를 통제
👉 이게 “닫혀 있지 않은 설계”야
추천 구조 (이게 제일 안정적)
protocol SocialTokenProviding {
func fetchAccessToken() async throws -> String
}
enum SocialLoginProvider {
case apple
case google
case kakao
case naver
}
/// 소셜 로그인(Kakao, Naver)을 Firebase 인증으로 연결하는 Coordinator 인터페이스입니다.
///
/// 이 Coordinator는
/// - Kakao / Naver SDK에서 발급된 accessToken을 전달받아
/// - Firebase Auth (또는 Firebase Functions)를 통해
/// 공용 인증 플로우를 수행하는 책임을 가집니다.
///
/// AuthService는 이 Protocol에만 의존하며,
/// 각 소셜 로그인 SDK의 구현 디테일을 알 필요가 없습니다.
///
/// 👉 역할 요약
/// - 소셜 로그인 Provider 간 분기 처리
/// - Firebase 인증 공통 로직 캡슐화
/// - AuthService와 소셜 SDK 사이의 중간 계층
protocol SocialAuthCoordinating {
func signIn(
with accessToken: String,
provider: SocialLoginProvider
) async throws
}
실제 흐름
[LoginVC]
↓
[KakaoAuthProvider] ── fetchAccessToken()
↓
[SocialAuthCoordinator] ── Firebase / Functions
↓
[AuthService] ── auth state 관리728x90
LIST
'PulseBoard' 카테고리의 다른 글
| KakaoAuthHandler는 “무엇을 기준으로 설계했나?” (0) | 2025.12.26 |
|---|---|
| ▶️ index.js 파일 설치기 (버전 이슈 해결 포함) (0) | 2025.12.26 |
| 🚀 axios 설치와 역할 - 서버에서 토큰 검증이 필요한 이유! (0) | 2025.12.26 |
| Firebase Cloud Functions index.js 완전 해설 (0) | 2025.12.25 |
| Firebase Authentication의 OpenID Connect를 쓰지 않고Cloud Functions + Custom Token으로 Kakao 로그인을 구현한 이유 (1) | 2025.12.25 |