티스토리 뷰

Firebase는 구글에서 만든 플랫폼으로, 별도의 서버를 만들 필요 없이 사용자 인증 및 관리를 할 수 있도록 해준다. 일반 이메일 인증 부터 구글 이메일, 애플 아이디 등 다양한 소셜 로그인 등을 지원하고, 공식 홈페이지에서 모든 플랫폼에 대한 상세한 사용 메뉴얼도 제공한다.

 

 

 

Cocoapods

동명의 개발 팀에서 만든 dependency management 프로그램이다. mac 터미널에서 사용하는 프로그램으로, framework를 관리한다. 예를 들어 프로젝트에서 GoogleSignIn framework를 사용하려고 한다. google이 제공하는 링크를 찾아서 framework를 다운 받고 프로젝트가 있는 위치로 옮긴 뒤, 프로젝트의 의존성 경로와 plist 등을 직접 수정하는 방법과 cocoapods으로 자동 설치하는 방법이 있다.

터미널을 열고 아래 명령어를 입력하면 cocoapods이 설치된다.

sudo gem install cocoapods

cocoapods은 Podfile이라는 텍스트 파일을 사용한다. 이 텍스트 파일 안에는 사용자가 설치하고자 하는 framework들을 작성할 수 있다. 직접 Podfile을 만들어서 사용할 수도 있고, 사용하고자 하는 프로젝트 경로로 이동해서 명령어를 입력해, 프로젝트에 맞는 default Podfile을 만들 수도 있다.

pod init

만들어진 Podfile은 텍스트 에디터로 열어서 내용을 볼 수 있다. #으로 시작하는 것들은 주석이다. target 프로젝트에 대해 do부터 end 까지 수행할 명령을 나열할 수 있다. 예를 들어 MyProject라는 프로젝트에 GoogleSignIn framework를 추가한다고 하면

target 'MyProject' do
  use_frameworks!
  pod 'GoogleSignIn'
end

처럼 작성할 수 있다.

 

 

 

install GoogleSignIn

먼저 구글 로그인을 구현 해보자. Firebase는 굳이 구글 아이디가 아니라 아무 이메일 주소를 가지고 로그인할 수 있지만 구글에서 만든 플랫폼이니, 구글 로그인을 먼저 넣어 보자. Podfile을 열고 do-end 사이에 GoogleSignIn framework를 사용하겠다는 명령을 입력하고 저장한다.

pod 'GoogleSignIn'

그 후 터미널에서 pod 명령어로 framework를 설치한다. install을 포함해서 앞으로 모든 명령은 프로젝트 경로에서 실행한다.

pod install

뭔가 설치가 되고 있다는 내용이 출력이 되고 폴더에 여러가지 파일이 생긴 것을 볼 수 있다. cocoapods는 framework를 설치하면서 Pods라는 프로젝트를 만드는데, 이 프로젝트와 원래 있던 프로젝트, framework dependency 등을 모두 포함하고 있는 .xcworkspace라는 workspace를 생성한다. visual studio의 solution과 비슷한 개념인 것 같다.

기존 프로젝트가 열려 있다면 종료하고, 새로 생긴 .xcworkspace를 실행한다. 이제 GoogleSignIn framework를 사용할 준비가 끝났다.

import GoogleSignIn

이제 코드 내에서 필요한 부분에 GoogleSignIn을 import하여 사용할 수 있다.

 

 

 

GooglePlatform

아무나 구글 로그인을 사용할 수는 없고, 구글에서 발행한 클라이언트 ID를 가지고 있는 클라이언트 만이 로그인 할 수 있기 때문에 먼저 프로젝트를 Google Console에 등록해야 한다.

Google Console

콘솔로 이동해서 프로젝트를 만들고 사용자 인증 정보 탭에서 새로운 OAuth 인증을 만든다.

 

이 때 필요한 번들 ID는 프로젝트 general 탭에서 찾을 수 있다.

 

발행 받은 클라이언트 ID를 복사한 후 다시 프로젝트로 돌아와서 클라이언트 ID를 설정한다. 프로그램이 실행 될 때 설정해야 하니까 보통 AppDelegate의 didFinishedLaunch 부분에 작성한다고 한다.

 

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
	GIDSignIn.sharedInstance().cliendID = "paste client ID here"
	return true
}

 

URL scheme도 설정 해준다. 이 값은 클라이언트 ID의 순서를 거꾸로 바꿔서 com.googleusercontent.apps.client_id 순서로 입력해 주어야 한다.

 

직접 info.plist에 입력할 수도 있다.

 

 

 

 

GIDSignInButton

먼저 어떤 식으로 sign in 로직이 돌아가는 지 그려보자.

 

sign in 요청을 처리한다.

 

로그인 버튼을 추가하고자 하는 ViewController로 이동해서 delegate와 presentingViewController를 설정한다. 버튼을 눌렀을 때 presentingViewController로 설정된 ViewController에서 present를 호출하여 구글 로그인 view를 띄우며, 로그인이 완료 되었을 때 delegate를 통해 이벤트를 처리할 수 있다.

 

GIDSignIn.sharedInstance().presentingViewController = self
GIDSignIn.sharedInstance().delegate = self

 

GIDSingInButton 이라는 view를 제공하며, 이 view는 style별로 크기가 고정되어 있기 때문에 UILabel 처럼 위치 constraint만 정해주면 된다.

 

3가지 스타일을 제공한다.

 

또한 일반 버튼과 달리 action에 대한 처리가 모두 GIDSignIn에서 처리되기 때문에 별도로 target action을 만들어 줄 필요가 없다.

 

let googleButton = GIDSignInButton()
googleButton.style = .standard
view.addSubview(googleButton)
// position constraints ...

 

ViewController를 GIDSignInDelegate로 확장 하려면 sign이라는 함수를 정의해야 한다. 이 sign함수는 로그인이 구글 로그인 view가 성공적으로 로그인을 끝내고 dismiss되면 호출되는 함수로 로그인 된 user 정보를 받을 수 있다.

 

extension LoginViewController : GIDSignInDelegate {
	func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
		// handle login
		if let authenication = user.authenication {
			print("google sign in \(authenication.idToken)")
		}
	}
}

 

이렇게 받은 user의 token을 가지고 여러 로직에 활용할 수 있다.

 

 

 

Firebase

원래 하고자 했던 목표는 firebase와 연동하는 것 이었다. 이제 token을 가지고 firebase와 연동 해보자. 다시 Podfile을 열고 Firebase/Auth framework을 설치한다.

 

// Podfile
pod 'Firebase/Auth'

// terminal
import Firebase

 

GoogleSignIn과 마찬가지로 먼저 Firebase 콘솔에 클라이언트를 등록해야 한다.

Firebase Console

프로젝트를 만든 후 제공하는 GoogleService-Info.plist를 프로젝트에 추가한다.

 

Google Console에서 만든 프로젝트를 import해서 사용할 수도 있다.

 

위에서 GIDSignIn.clientID를 설정했던 부분으로 가서 FirebaseApp을 구성한다. Firebase 서버에 해당 클라이언트가 로그인 되어 있는지 확인하고 Auth를 초기화 한다. plist에 클라이언트 ID가 있기 때문에 기존에 있던 코드는 삭제한다.

 

// GIDSignIn.sharedInstance().clientID = "client id"
FirebaseApp.configure()

 

Firebase에 로그인 하기 위해서는 AuthCredential이라는 오브젝트를 필요로 한다. 이 오브젝트는 Firebase가 지원하는 모든 소셜 로그인 token을 사용해서 만들 수 있는데, 위에서 GoogleSignIn 로그인을 만들었기 때문에 GoogleAuthProvider로 credential을 만들고 연동한다.

 

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
	guard let authenication = user.authenication else {
		return
	}

	// make credential
	let credential = GoogleAuthProvider.credential(
		withIDToken: authenication.idToken, 
		accessToken: authenication.accessToken)

	// sign in to firebase
	Auth.auth().signIn(with: credential, completion: {result, error in
		// handle result
	})
}

 

GoogleSignIn과 달리 범용적인 인증을 처리할 수 있도록 만들었기 때문에 버튼은 물론이고, GIDSignInDelegate같은 delegate도 없다. 대신 listener를 사용해서 sign in/out에 대한 이벤트를 처리할 수 있다.

 

// add listener
handle = Auth.auth().addStateDidChangedListener({auth, user in 
	if let user = user {
		// sign in
	} else {
		// sign out
	}
})

// remove listener
Auth.auth().removeStateDidChangedListener(handle)

 

한 번 연동된 클라이언트는 Auth.auth().signOut()으로 sign out 하기 전 까지 연동이 유지된다. 앱을 실행할 때 FirebaseApp.configure()으로 연동정보를 초기화 하기 때문에 앱을 다시 실행해도 인증이 유효하다면 유효한 uid를 사용할 수 있다.

 

if user = Auth.auth().currentUser {
	print(user.uid)
	// already signed in
} else {
	// no user
	// have to sign in
}

 

configure() 실행 후에 위처럼 이미 인증이 유효한 사용자 인지 식별할 수 있다.

공식 페이지에서 메뉴얼을 제공하기도 하고 오히려 더 어려운 것 같아서 이렇게 별도로 포스팅을 쓰는 게 의미가 없을 거라는 생각도 했지만 메뉴얼을 따라 하면서 겪었던 시행착오를 기록하고 공유하기 위해서 작성했다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함