Firebase Authentication을 활용한 Google Login

KEH·2021년 7월 15일
0
post-thumbnail
post-custom-banner

Firebase Authentication을 활용해 구글 로그인을 연동해보도록 하겠다.
구글 로그인의 순서는

  1. 구글 아이디로 로그인 버튼을 누른다.
  2. 구글 로그인 화면으로 이동한다.
  3. 로그인에 성공하면 구글로부터 IdToken을 전달 받는다.
  4. IdToken으로 Firebase 사용자 인증 정보를 교환 받고 이 정보를 사용해 Firebase에 인증한다.

더 자세한 내용은 공식 문서를 참고하길 바란다.

사전 준비

  1. build.gradle(Module) 파일에 구글 로그인에 필요한 라이브러리들을 추가한다.

    빨간줄이 그거져 있는 세 가지 라이브러리가 필요하다.
  2. 앱의 SHA-1 디지털 지문을 지정한다.
    첫 번째로 안드로이드 스튜디오 프로젝트에서 SHA-1을 복사해야 한다. View->Tool Windows->Gradle->Tasks->android->signingReport로 이동하면 SHA-1을 확인할 수 있다.

이후 firebase 콘솔로 이동해 프로젝트 설정 -> 디지털 지문 추가를 클릭해 복사한 SHA-1을 등록한다.

  1. firebase 프로젝트에서 Authentication->Sign-in method->Google->사용설정 활성화를 통해 구글 로그인을 사용할 수 있도록 해 준다.

Google 로그인 및 GoogleSignInClient 개체 구성

구글 로그인 후 앱에서 필요한 사용자 정보를 요청하기 위해 구글로그인을 구성하는 단계이다. 아래 코드는 DEFAULT_SIGN_IN 매개변수를 사용해 사용자 ID와 기본 프로필 정보를 요청하도록 만들었다. 구성된 GoogleSignInOptions 객체를 활용해 GoogleSignInClient 객체를 생성한다.

var googleSignInClient: GoogleSignInClient? = null

//GoogleSignInOptions 객체 생성
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(clientId)
            .requestEmail()
            .build()
            
//GoogleSignInClient 객체 생성
googleSignInClient = GoogleSignIn.getClient(context, gso)

구글 로그인 화면으로 이동하기

다음은 로그인 화면에서 구글 아이디로 로그인 버튼을 누르면 우리가 잘 아는 구글 로그인 화면으로 이동하도록 하는 코드이다.

override fun onCreate(savedInstanceState: Bundle?) {
	...
    
	binding.googleLoginButton.setOnClickListener {
		googleSignIn()
	}
}

fun googleSignIn() {
	//Launcher를 실행해 LoginActivity -> 구글 로그인 화면으로 이동.
	launcher!!.launch(getString(R.string.default_web_client_id))
}

LoginActivity.kt에서 구글로그인 버튼을 클릭하면 googleSignIn() 함수가 호출되도록 작성하였다. 이 때 googleSingIn() 함수는 구글로그인 인텐트를 생성해 해당 화면으로 이동하도록 하는 함수이다.

startActivityForResult()가 deprecated 되면서 registerForActivityResult()를 사용했다.

//LoginActivity에서 구글 아이디로 로그인 버튼을 누르면 구글 로그인 화면으로 이동하는 intent를 만드는 함수.
override fun createIntent(context: Context, clientId: String): Intent {
	//구글로그인 초기설정
        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(clientId)
            .requestEmail()
            .build()
        googleSignInClient = GoogleSignIn.getClient(context, gso)

        //구글로그인 화면 intent
        val signInIntent = googleSignInClient!!.signInIntent

        return signInIntent
}

ActivityResultContract<I, O> 추상클래스를 상속한 서브 클래스를 만들어 Contract를 생성했고, createIntent() 추상메서드 안에 인텐트를 생성하는 코드를 추가했다.

구글 로그인 후 IdToken 전달 받기

로그인에 성공하면 구글에서는 로그인한 사용자의 정보를 얻을 때 필요한 IdToken을 전달한다. 이를 가져오는 코드를 작성해 볼 것이다. ActivityResultContract<I, O> 추상클래스의 추상메소드 중에 parseResult()가 있다. 이 메소드를 활용해 구글 로그인 화면에서 로그인 화면으로 다시 돌아온 후 구글 로그인 화면으로부터 전달 받은 IdToken을 가져오는 코드를 작성해 보자.

//구글 로그인 화면에서 다시 LoginActivity로 돌아올 때 호춯되는 함수.
override fun parseResult(resultCode: Int, intent: Intent?): String? {
	return when (resultCode) {
		//정상적으로 로그인이 이뤄진 경우 getTokenId 함수를 통해 얻은 tokenId를 LoginActivity에 전달.
            	Activity.RESULT_OK -> getTokenId(intent)
            	else -> null
        }
}

//tokenId를 리턴해주는 함수.
fun getTokenId(data: Intent?): String? {
        val task = GoogleSignIn.getSignedInAccountFromIntent(data)
        try {
            // Google Sign In was successful, authenticate with Firebase
            val account = task.getResult(ApiException::class.java)!!
            return account.idToken
        } catch (e: ApiException) {
            // Google Sign In failed, update UI appropriately
            println("getTokenId() tokenId를 정상적으로 얻어오지 못함=>\n${e}")
            return null
        }
}

IdToken을 활용해 Firebase 인증하기

IdToken으로 Firebase 사용자 인증 정보로 교환을 한 후 교환된 정보를 이용해 Firebase에 인증할 수 있다.

val credential = GoogleAuthProvider.getCredential(idToken, null)

//Firebase 사용자 인증 정보(credential)를 사용해 Firebase에 인증.
auth!!.signInWithCredential(credential)
	.addOnCompleteListener(this@LoginActivity) { task: Task<AuthResult> ->
	if (task.isSuccessful) {
		// Sign in success, update UI with the signed-in user's information
		Toast.makeText(
			this@LoginActivity,
                        getString(R.string.signin_complete),
                        Toast.LENGTH_SHORT
		).show()
	} else {
		println("firebaseAuthWithGoogle => ${task.exception}")
		Toast.makeText(
			this@LoginActivity, getString(R.string.signin_google_faile),
                        Toast.LENGTH_SHORT
		).show()
	}
}

credential 변수가 IdToken으로 교환 받은 Firesbase 사용자 인증 정보이고, signInWithCredential() 메서드를 통해 Firebase에 인증을 진행한다.

profile
개발을 즐기고 잘하고 싶은 안드로이드 개발자입니다 :P
post-custom-banner

0개의 댓글