[IOS] - 카카오 , 파이어베이스 로그인 연동 구현하기

Shawn·2021년 6월 30일
5

IOS

목록 보기
1/5

파이어베이스 카카오톡 로그인 연동하기

나는 앱을 개발할 때 데이터베이스로 파이어베이스를 자주 이용한다. 처음 배운 DB가 파이어베이스이기도 하고, 명령어가 간단해서 사용하기 편하다.

또한,
파이어베이스에서는 다양한 기능을 지원한다.
푸쉬 알림, Realtime Database, 저장소, 로그인 등...
그중에서 로그인 기능에 대해 알아보겠다.

파이어베이스 로그인??

모든 앱에서 빠질 수 없는게 로그인이다.

출처. Firebase Google

위에 사진은 Firebase 에서 기본적으로 제공하는 여러 로그인 인증 방법들이다.

사실 더 많다...

그런데 정작 우리가 가장 많이 본 카카오톡 로그인은 제공하고 있지 않다.
그래서 이게 옳은 방법인지는 모르겠지만, 카카오톡 로그인과 파이어베이스 로그인을 연동해보려고 한다.

왜 둘 다..?

일단 처음 드는 의문점은 왜 파이어베이스와 카카오톡 로그인을 둘 다 해야하는 가? 이다. 둘 중 하나만 하면 안돼? 라고 묻는 사람들이 있겠지만
정답은 안돼 이다.
Firebase 에서 제공하는 Realtime Database 나 Storage 를 이용하려면 FirebaseLogin 이 되어있는 상태이어야 한다. 그렇지 않으면 Access가 불가능 하다는 에러메세지를 받게 된다. 그래서 우리는 Kakao Login 과 Firebase Login 을 함께 구현해줘야한다.

연동 방법

카카오 개발자 홈페이지에서 앱을 등록하고 엑스코드에 info.plist 를 등록하는 과정은 생략하겠다.

이 블로그 에서 잘 설명해주고 있다.

이 연동방법은 모든 세팅이 끝나고 나서 하는 방법이다. 카카오 개발자 홈페이지에 잘 나와있는 세팅을 모두 끝내고서 따라와주길 바란다.

1. Kakao 로그인 버튼을 만든 후, 코드에 Outlet으로 연결해주자.

2. AuthApi.hasToken() 명령어를 통해 토큰 존재 유무를 파악하자.

2번과정은 굉장히 중요한 과정이다. 여기서 말하는 토큰은 로그인을 하기 위한 유저의 정보가 담긴 열쇠 같은 것인데, 토큰이 있다면 이미 로그인이 되어있는 것이다. 따라서 위에 Kakao id 버튼을 눌러보면, id가 nil이 나오지 않을 것이다.

        if AuthApi.hasToken() {
            UserApi.shared.accessTokenInfo { _, error in
                if let error = error {
                    print("_________login error_________")
                    print(error)
                    if UserApi.isKakaoTalkLoginAvailable() {
                        UserApi.shared.loginWithKakaoTalk { oauthToken, error in
                            if let error = error {
                                print(error)
                            } else {
                                print("New Kakao Login")
                                
                                //do something
                                _ = oauthToken
                           
                                // 로그인 성공 시
                                UserApi.shared.me { kuser, error in
                                    if let error = error {
                                        print("------KAKAO : user loading failed------")
                                        print(error)
                                    } else {
                                        Auth.auth().createUser(withEmail: (kuser?.kakaoAccount?.email)!, password: "\(String(describing: kuser?.id))") { fuser, error in
                                            if let error = error {
                                                print("FB : signup failed")
                                                print(error)
                                                Auth.auth().signIn(withEmail: (kuser?.kakaoAccount?.email)!, password: "\(String(describing: kuser?.id))", completion: nil)
                                            } else {
                                                print("FB : signup success")
                                            }
                                        }
                                    }
                                }
                                
                                let VC = self.storyboard?.instantiateViewController(identifier: "MainViewController") as! MainViewController
                                VC.modalPresentationStyle = .fullScreen
                                self.present(VC, animated: true, completion: nil)
                                
                            }
                        }
                    }
                }

하지만 토큰의 유효기간이 만료된 경우, 토큰이 존재함에도 로그인이 되지 않을 수가 있다. 그럴땐 UserApi 를 다시불러와, UserApi.loginWithKakaoTalk 명령어로 토큰을 갱신해주면 된다.

카카오 토큰을 받아오는데 성공했으면, 이젠 파이어 베이스 로그인을 할 차례이다. Auth.auth().createUser 을 통해 이메일은 카카오토큰의 이메일, 비밀번호는 카카오 토큰의 id (Firebase 의 uid같은 역할을 한다.) 으로 계정을 생성한다. 그런데 이미 계정이 생성되어있는 경우 에러메세지를 띄운 후, Auth.auth().signIn을 통해 로그인을 해준다.

3. 토큰이 없는 경우

처음부터 토큰이 없는, 처음 앱을 킨 상황이면, 토큰이 만료되어 갱신해주는 상황처럼 해주면 된다.

            if UserApi.isKakaoTalkLoginAvailable() {
                UserApi.shared.loginWithKakaoTalk { oauthToken, error in
                    if let error = error {
                        print(error)
                    } else {
                        print("New Kakao Login")
                        
                        //do something
                        _ = oauthToken
                   
                        // 로그인 성공 시
                        UserApi.shared.me { kuser, error in
                            if let error = error {
                                print("------KAKAO : user loading failed------")
                                print(error)
                            } else {
                                Auth.auth().createUser(withEmail: (kuser?.kakaoAccount?.email)!, password: "\(String(describing: kuser?.id))") { fuser, error in
                                    if let error = error {
                                        print("FB : signup failed")
                                        print(error)
                                        Auth.auth().signIn(withEmail: (kuser?.kakaoAccount?.email)!, password: "\(String(describing: kuser?.id))", completion: nil)
                                    } else {
                                        print("FB : signup success")
                                    }
                                }
                            }
                        }
                        
                        let VC = self.storyboard?.instantiateViewController(identifier: "MainViewController") as! MainViewController
                        VC.modalPresentationStyle = .fullScreen
                        self.present(VC, animated: true, completion: nil)
                    }
                }
            }

UserApi.isKakaoTalkLoginAvailable() 명령어는 카카오톡 설치 유무를 판단한다. 카카오톡이 설치 되어있으면 loginWithKakaoTalk 으로 토큰을 받고, 파이어베이스 로그인 까지 해준다.

전체 코드

import UIKit
import KakaoSDKUser
import KakaoSDKAuth
import FirebaseAuth

class LoginViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

}

override func viewDidAppear(_ animated: Bool) {
    if Auth.auth().currentUser?.uid != nil {
        print("auto login success")
        let VC = self.storyboard?.instantiateViewController(identifier: "MainViewController") as! MainViewController
        VC.modalPresentationStyle = .fullScreen
        self.present(VC, animated: true, completion: nil)
    } else {
        print("auto login failed")
    }
}

@IBAction func KakaoLogin(_ sender: Any) {
    if AuthApi.hasToken() {
        UserApi.shared.accessTokenInfo { _, error in
            if let error = error {
                print("_________login error_________")
                print(error)
                if UserApi.isKakaoTalkLoginAvailable() {
                    UserApi.shared.loginWithKakaoTalk { oauthToken, error in
                        if let error = error {
                            print(error)
                        } else {
                            print("New Kakao Login")
                            
                            //do something
                            _ = oauthToken
                       
                            // 로그인 성공 시
                            UserApi.shared.me { kuser, error in
                                if let error = error {
                                    print("------KAKAO : user loading failed------")
                                    print(error)
                                } else {
                                    Auth.auth().createUser(withEmail: (kuser?.kakaoAccount?.email)!, password: "\(String(describing: kuser?.id))") { fuser, error in
                                        if let error = error {
                                            print("FB : signup failed")
                                            print(error)
                                            Auth.auth().signIn(withEmail: (kuser?.kakaoAccount?.email)!, password: "\(String(describing: kuser?.id))", completion: nil)
                                        } else {
                                            print("FB : signup success")
                                        }
                                    }
                                }
                            }
                            
                            let VC = self.storyboard?.instantiateViewController(identifier: "MainViewController") as! MainViewController
                            VC.modalPresentationStyle = .fullScreen
                            self.present(VC, animated: true, completion: nil)
                            
                        }
                    }
                }
            } else {
                print("good login")
                let VC = self.storyboard?.instantiateViewController(identifier: "MainViewController") as! MainViewController
                VC.modalPresentationStyle = .fullScreen
                self.present(VC, animated: true, completion: nil)
            }
        }
    } else {
        if UserApi.isKakaoTalkLoginAvailable() {
            UserApi.shared.loginWithKakaoTalk { oauthToken, error in
                if let error = error {
                    print(error)
                } else {
                    print("New Kakao Login")
                    
                    //do something
                    _ = oauthToken
               
                    // 로그인 성공 시
                    UserApi.shared.me { kuser, error in
                        if let error = error {
                            print("------KAKAO : user loading failed------")
                            print(error)
                        } else {
                            Auth.auth().createUser(withEmail: (kuser?.kakaoAccount?.email)!, password: "\(String(describing: kuser?.id))") { fuser, error in
                                if let error = error {
                                    print("FB : signup failed")
                                    print(error)
                                    Auth.auth().signIn(withEmail: (kuser?.kakaoAccount?.email)!, password: "\(String(describing: kuser?.id))", completion: nil)
                                } else {
                                    print("FB : signup success")
                                }
                            }
                        }
                    }
                    
                    let VC = self.storyboard?.instantiateViewController(identifier: "MainViewController") as! MainViewController
                    VC.modalPresentationStyle = .fullScreen
                    self.present(VC, animated: true, completion: nil)
                }
            }
        }
    }
}
@IBAction func kakaoid_check(_ sender: Any) {
    UserApi.shared.me { user, error in
        print(user?.id)
    }
}

@IBAction func fbuid_check(_ sender: Any) {
    print(Auth.auth().currentUser?.uid)
}

}


ViewDidAppear 에 이미 uid 가 생성되어있다면 자동 로그인 까지 추가해주며 연동을 시켜보았다. 이 방법을 이용하면 다른 로그인도 손쉽게 할 수 있을 것 같다.
profile
iOS 개발, Flutter 개발, Swift, Dart, 42 Seoul 3기

1개의 댓글

comment-user-thumbnail
2021년 6월 30일

stop watching porno Jinseo.

답글 달기