Sure, Why not?

kakao 로그인 본문

💻

kakao 로그인

joho2022 2025. 3. 18. 12:00

디자인 가이드

 

 

초기세팅

https://developers.kakao.com/docs/latest/ko/kakaologin/prerequisite

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

카카오 소셜 로그인 연동을 하기 위한 첫 번째 단계는

문서를 보고 kakao developers에서 초기 세팅을 해준다.

(활성화 설정, 동의항목, 플랫폼 등등 )

 

 

kakao SDK

 

https://developers.kakao.com/docs/latest/ko/ios/getting-started

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

iOS SDK 2.23.0 버전부터 Cocoapods로 설치를 지원하지 않습니다. 때문에,

SPM으로 설치하였음

 

 

 

 

커스텀 URL 스킴 설정

카카오톡 로그인 후 서비스 앱으로 돌아오기 위해 설정해준다.

 

네이티브 앱 키는 

내 애플리케이션 - 앱 설정 - 앱 키 

확인할 수 있다.

 

그리고 네이티브 앱 키를 안전하게 관리하기 위해서

 

# Xcode Configuration
*.xcconfig

gitignore에 환경설정 파일을 추가해서 커밋을 제외하도록 하고,

 

KAKAO_APP_KEY = "네이티브 앱 키"

Secrets.xcconfig 파일을 생성해서 키를 관리하고자 하였다.

 

그리고 info.plist에 등록을 해준다.

 

이제 환경변수를 가지고, 커스텀 URL 스킴을 설정하였다.

 

 

 

 

앱 실행 허용 목록

 

카카오톡 앱을 실행할려면 info.plist에서 앱 실행 허용 목록을 설정해야 한다.

 

 

 

 

앱 상단에 kakaoSDK 초기화

로그인을 사용하기 위해서, 앱 실행시에 한번 kakaoSDK를 초기화해줘야 함

 

import SwiftUI
import KakaoSDKCommon
import KakaoSDKAuth

@main
struct LoginPracticeApp: App {
    
    init() {
        let kakaoAppKey = Bundle.main.infoDictionary?["KAKAO_APP_KEY"] as? String ?? ""
        KakaoSDK.initSDK(appKey: kakaoAppKey)
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onOpenURL { url in
                    if AuthApi.isKakaoTalkLoginUrl(url) {
                        _ = AuthController.handleOpenUrl(url: url)
                    }
                }
        }
    }
}

그리고 카카오톡에서 서비스 앱으로 돌아왔을 때 카카오 로그인 처리를 정상적으로 완료하기 위해 

SwiftUI 앱에서는 onOpenURL()을 사용하여 handleOpenUrl()을 추가한다.

 


onOpenURL()

딥링크를 통해 전달된 URL를 감지하고, 해당 URL을 기반으로 특정화면으로 이동하는 메서드

 

딥링크

앱 외부에서 특정화면으로 이동하게 해주는 링크 기술

 

 

로그인

iOS에서는 소셜 로그인을 도입할 경우, 애플 로그인도 함께 제공되어야 한다.

이에 따라, 각 로그인 방식을 확장성을 생각해서 어댑터 패턴으로 구현해서 관리하도록 했다.

 

import Foundation

protocol SocialLoginService {
    func login() async throws -> UserInfo
    func logout() async throws
    func getServiceName() -> String
}

해당 프로토콜로 각 소셜 로그인 방식이 서로 다른 로직을 가지더라도, 일관된 인터페이스로 관리할 수 있도록 설계했다.

 

 

 

카카오톡으로 로그인

 

사용자 정보 가져오기

https://developers.kakao.com/docs/latest/ko/kakaologin/ios#req-user-info

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

 

func login() async throws -> UserInfo {
        return try await withCheckedThrowingContinuation { continuation in
            UserApi.shared.loginWithKakaoTalk { OAuthToken, error in
                if let error = error {
                    print("==== Kakao Login Error ====")
                    print("Error: \(error.localizedDescription)")
                    print("==============================")
                    
                    continuation.resume(throwing: AdapterError.loginFailed(serviceName: .kakao))
                    return
                }
                
                if let token = OAuthToken?.accessToken {
                    print("Access Token Received: \(token)")
                } else {
                    print("Access Token Not Found")
                }
                
                UserApi.shared.me { user, error in
                    if let error = error {
                        print("==== Kakao Login Error ====")
                        print("Error: \(error.localizedDescription)")
                        print("==============================")
                        
                        continuation.resume(throwing: AdapterError.loginFailed(serviceName: .kakao))
                        return
                    }
                    
                    guard let user = user,
                          let id = user.id,
                          let name = user.kakaoAccount?.profile?.nickname,
                          let email = user.kakaoAccount?.email else {
                        continuation.resume(throwing: AdapterError.userInfoNotFound(serviceName: .kakao))
                        return
                    }
                    
                    let userInfo = UserInfo(
                        id: String(id),
                        name: name,
                        email: email
                    )
                    
                    continuation.resume(returning: userInfo)
                }
            }
        }
    }

 

이미 비동기 API가 제공되고 있지만, async/await을 통한 비동기 처리를 원하기 때문에

withCheckedThrowingContinuation을 이용해 해당 API를 변환하여 사용하고자 한다.

 

 

로그아웃

func logout() async throws {
        return try await withCheckedThrowingContinuation { continuation in
            UserApi.shared.logout { error in
                if let error = error {
                    print("==== Kakao Logout Error ====")
                    print("Error: \(error.localizedDescription)")
                    print("==============================")
                    
                    continuation.resume(throwing: AdapterError.logoutFailed(serviceName: .kakao))
                    return
                }
                
                continuation.resume()
            }
        }
    }

 

kakao SDK에서 기본적으로 제공되는 error가 있지만, 다양한 로그인 서비스에서 발생하는 에러를 공통된 방식으로 처리하기 위해

일관되고 범용적으로 처리할 수 있도록 AdapterError를 따로 구현했다.

 

( 아직 로그인 구현은 kakao가 처음이기도 하지만 )

이건 나중에 여러 소셜 로그인을 구현하면서 적합한 방법이었는지는 다시 고민해봐야겠다.

 

 


다음으로 각각 단일책임으로 하는 객체들인 AuthManager, KeyChainManager 만들어줬다.

 

AuthManager는 어댑터의 상태를 공유하며 로그인 방식을 유연하게 교체할 수 있도록 하기 위해 싱글톤패턴으로 하였고,

중앙집중적으로 처리하는 로그인 관련 최상위 객체이다.

 

KeyChainManager은 말 그대로 토큰은 민감한 데이터이기 때문에 키체인을 사용해서 안전하게 관리하고자 했다.

해당 객체는 상태를 관리하지 않기 때문에, 단순한 유틸성 특징 클래스로 싱클톤이 아닌,

static메서드로 사용하고자 하였다.

 

결과

간단한 로그인 버튼을 만들어줬다. 버튼을 누르면 push
정상적으로 응답받은 것을 확인

 


다양한 로그인 서비스를 유지보수와 확장성에 염두하여,

어댑터 패턴으로 설계하고 첫 번째인 카카오를 구현해봤는데,

여러 개 로그인이 마련되어야 어댑터 패턴이 와닿을 것 같다.

 

결국 흐름은

View → ViewModel → AuthManager → SocialLoginService → 소셜 로그인 순으로 요청되고

응답은 자연스럽게 역순으로 흘러간다.

 

그리고 추후 소셜로그인 추가하게 되면

SocialLoginService만 교체하면 확장하는데 문제 없이 작업할 수 있게 될 것 같다

 

 

 

 

GitHub - joho2022/LoginPractice

Contribute to joho2022/LoginPractice development by creating an account on GitHub.

github.com

 

'💻' 카테고리의 다른 글

Google 로그인  (0) 2025.03.21
Apple 로그인  (0) 2025.03.19
Deadlock  (1) 2025.03.02
Localization 다국어 지원  (0) 2025.02.21
앱스토어 출시 과정 (+ TestFlight 업로드 )  (0) 2025.02.11