티스토리 뷰

반응형

구글 로그인에 대해서 간단하게 알아보려고합니다.

구글 로그인을 하기 위해서는 Firebase에 App을 등록한 다음 google-services.json 파일을 해당 프로젝트에 넣어야합니다.

자세한 내용은 Firebase 개발자 문서에서 확인할 수 있습니다.

Firebase 기본 UI 로그인

 

build gradle에서 dependencies 을 등록합니다.

 

(app)build.gradle

dependencies {
    // Firebase
    implementation 'com.google.firebase:firebase-core:16.0.8'
    implementation 'com.google.firebase:firebase-auth:16.0.4'
    implementation 'com.google.android.gms:play-services-auth:16.0.1'
}

 

Firebase로 인증하기

1. Android 앱에 Google 로그인 통합하기 페이지를 참고해 Google 로그인을 앱에 통합합니다.

GoogleSignInOptions 객체를 구성할 때 requestIdToken을 호출합니다.

 

//구글
val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.google_default_web_client_id))
.requestEmail()
.build()
googleSignInClient = GoogleSignIn.getClient(this, googleSignInOptions)
googleAuth = FirebaseAuth.getInstance()

 

2. 서버의 클라이언트 ID를 requestIdToken 메소드에 전달해야 합니다.

 

private fun signIn() {
    val signInIntent = googleSignInClient.signInIntent
    startActivityForResult(signInIntent, RC_SIGN_IN)
}

public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
    if (requestCode == RC_SIGN_IN) {
        val task = GoogleSignIn.getSignedInAccountFromIntent(data)
        try {
            // Google Sign In was successful, authenticate with Firebase
            val account = task.getResult(ApiException::class.java)
            firebaseAuthWithGoogle(account!!)
        } catch (e: ApiException) {
            // Google Sign In failed, update UI appropriately
            Log.w(TAG, "Google sign in failed", e)
            // ...
        }
    }
}

 

3. 로그인 작업의 onCreate 메소드에서 FirebaseAuth 객체의 공유 인스턴스를 가져옵니다.

 

private lateinit var auth: FirebaseAuth// ...
// Initialize Firebase Auth
auth = FirebaseAuth.getInstance()

 

4. 활동을 초기화 할 때 사용자가 현제 로그인인지 확인합니다.

 

public override fun onStart() {
    super.onStart()
    // Check if user is signed in (non-null) and update UI accordingly.
    val currentUser = auth.currentUser
    updateUI(currentUser)
}

 

5. 사용자가 정상적으로 로그인한 후에 GoogleSignInAccount 객체에서 ID 토큰을 가져와서 Firebase 사용자 인증 정보로 교환합니다. 가져온 Firebase 사용자 인증 정보를 사용해 Firebase에 인증합니다.

 

private fun firebaseAuthWithGoogle(acct: GoogleSignInAccount) {
    Log.d(TAG, "firebaseAuthWithGoogle:" + acct.id!!)

    val credential = GoogleAuthProvider.getCredential(acct.idToken, null)
    auth.signInWithCredential(credential)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCredential:success")
                    val user = auth.currentUser
                    updateUI(user)
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(TAG, "signInWithCredential:failure", task.exception)
                    Snackbar.make(main_layout, "Authentication Failed.", Snackbar.LENGTH_SHORT).show()
                    updateUI(null)
                }

                // ...
            }
}

 

signInWithCredential 에 대한 호출이 성공하면 getCurrentUser 메소드로 사용자의 계정 데이터를 가져올 수 있습니다.

 

소스코드

구글 로그인에 대한 전체적인 소스는 다음과 같습니다.

 

LoginActivity.kt

private const val RC_RIGN_IN = 300

class LoginActivity : AppCompatActivity() {
    companion object {
        private val TAG = LoginActivity::class.java!!.getSimpleName();
    }

    private lateinit var googleSignInOptions: GoogleSignInOptions
    private lateinit var googleSignInClient: GoogleSignInClient
    private lateinit var googleAuth: FirebaseAuth

    /**
     * ##########################
     *  Override Method
     * ##########################
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        //구글
        googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.google_default_web_client_id))
            .requestEmail()
            .build()
        googleSignInClient = GoogleSignIn.getClient(this, googleSignInOptions)
        googleAuth = FirebaseAuth.getInstance()

        initOnClickListener()
    }

    override fun onStart() {
        super.onStart()

        //현재 로그인 되어 있는지 확인
        val currentUser = googleAuth.currentUser
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == RC_RIGN_IN){
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            try {
                //Google Sign In was successful, authenticate with Firebase
                val account = task.getResult(ApiException::class.java)
                firebaseAuthWithGoogle(account!!)
            }catch (e: ApiException){
                Log.w(TAG, "Google sign in failed", e)
            }
        }

        super.onActivityResult(requestCode, resultCode, data)
    }

    /**
     * ##########################
     *  Local Method
     * ##########################
     */

    /**
     * 로그인 성공 시 호출
     * */
    fun successLogin(){
        startActivity(Intent(this, MainActivity::class.java))
        finish()
    }

    /**
     * =============================
     *  구글 로그인
     *  =============================
     */
    private fun googleSignIn(){
        googleSignInClient.signOut()
        val signInIntent = googleSignInClient.signInIntent
        startActivityForResult(signInIntent, RC_RIGN_IN)
    }

    /**
     * GoogleSignInAccount 객체에서 ID 토큰을 가져와서 Firebase 사용자 인증 정보로 교환하고 Firebase 사용자 인증 정보를 사용해 인증.
     */
    private fun firebaseAuthWithGoogle(acct: GoogleSignInAccount){
        LogUtils.d(TAG, "firebaseAuthWithGoogle: " + acct.id!!)

        val credential = GoogleAuthProvider.getCredential(acct.idToken, null)
        googleAuth.signInWithCredential(credential)
            .addOnCompleteListener(this){ task ->
                if(task.isSuccessful){
                    // Sign in success, update UI with the signed-in user's information
                    LogUtils.i(TAG, "signInWithCredential:success")
                    val user = googleAuth.currentUser
                    successLogin()
                } else{
                    Log.w(TAG, "signInWithCredential:failure", task.exception)
                    Snackbar.make(layout_main, "Authentication Failed.", Snackbar.LENGTH_SHORT).show()

                }
            }
    }
}

 

activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/layout_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".login.LoginActivity">

    <Button
            android:text="구글 로그인하기"
            android:layout_width="0dp"
            android:textStyle="bold"
            android:textColor="@android:color/white"
            android:layout_height="@dimen/_45sdp"
            android:textSize="@dimen/_13sdp"
            android:background="@android:color/holo_red_dark"
            android:id="@+id/btnGoogleLogin"
            app:layout_constraintBottom_toBottomOf="parent" 
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginBottom="30dp"/>
</android.support.constraint.ConstraintLayout>

 

마무리

구글 로그인에 대해서 알아봤습니다.

간단하게 구성할 수 있는 구글 로그인은 회원가입을 귀찮아 하는 유저들에게 편의성이 제공할 것으로 기대가 됩니다.

자세한 구글 로그인은 Firebase 개발자 문서에서 확인할 수 있습니다.

반응형
댓글