Firebase_Google_Authentication - boostcampwm-2024/and04-Nature-Album GitHub Wiki
โ Firebase Google Login ๊ธฐ๋ฅ
โ secrets gradle plugin๋ฅผ ์ฌ์ฉํ์ฌ local.properties ํค ๊ฐ ์จ๊ธฐ๊ธฐ
https://firebase.google.com/docs/auth/android/google-signin?hl=ko
Firebase Authentication ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ๊ตฌํํ๊ธฐ๋ก ํ๋ค.
ํ์ง๋ง ํด๋น ๋ฌธ์์ ์ฝ๋์ ๋๋ถ๋ถ์ด deprecated ๋์๊ธฐ์ ์๋์ ๊ณต์ ๋ฌธ์๋ฅผ ๋ฐ๋ผ๊ฐ๊ธฐ๋ก ํ๋ค.
https://developer.android.com/identity/sign-in/credential-manager-siwg?hl=ko
์ ๊ณต์ ๋ฌธ์์์๋ deprecated๋ BeginSignInRequest
๋์ Credential Manager
๋ฅผ ์ฌ์ฉํ๋ผ๊ณ ํ๋ค.
Credential Manager
์ ๋ํด์๋ ์๋์ Google Developers์์ ํ์ธํ ์ ์์๋ค.
Credential Manager๋ Android ํ๋ซํผ์ ๋ฏธ๋ํ ์ธ์ฆ ๋ฐฉ์์ผ๋ก, ์ฌ์ฉ์๊ฐ ์ฑ๊ณผ ์น์ฌ์ดํธ์ ๋ก๊ทธ์ธํ๋ ๋ฐฉ์์ ๊ฐ์ํํ๋ ๋์์ ํ์ธต ๊ฐํ๋ ๋ณด์์ ์ ๊ณตํ๋ค.
๋น๋ฐ๋ฒํธ์ ๋ค์ํ ๋ก๊ทธ์ธ ๋ฐฉ์์ผ๋ก ์ธํด ์ฌ์ฉ์์ ๊ฐ๋ฐ์ ๋ชจ๋์๊ฒ ๋ก๊ทธ์ธ ๊ณผ์ ์ด ๋ณต์กํด์ง ์ ์๋ค,
ํ์ง๋ง Credential Manager๋ Android์์ ํจ์ค์๋๋ฆฌ์ค ์ธ์ฆ ๋ฐฉ์(ํจ์คํค)๊ณผ ๊ธฐ์กด ๋ก๊ทธ์ธ ๋ฐฉ์์ ํ๋์ ์ธํฐํ์ด์ค๋ก ํตํฉํด ์ง์ํ๊ณ ์ด๋ฅผ ํตํด ๋ณด์์ฑ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํค๊ณ ๊ฐ๋ฐ์ ๋ณต์ก์ฑ์ ์ค์ผ ์ ์๋ค.
ํจ์คํค๋ก ํจ์ค์๋๋ฆฌ์ค ์ธ์ฆ ์ง์ํ๊ณ ๋ชจ๋ ๊ณ์ ์ ๋จ์ํ ์ธํฐํ์ด์ค์์ ํญ ํ ๋ฒ์ผ๋ก ์ด์ฉ ๊ฐ๋ฅํ๋ค.
์ ์ด๋ฏธ์ง์ ๊ฐ์ด ๋์ผ ๊ณ์ ์ ์ฌ๋ฌ ๋ก๊ทธ์ธ ๋ฐฉ๋ฒ์ด ์์ ๋, Credential Manager๋ ์ฌ์ฉ์์๊ฒ ์ต์ ์ ๋ก๊ทธ์ธ ๋ฐฉ์(ํจ์คํค, ๋น๋ฐ๋ฒํธ ๋ฑ)์ ์๋์ผ๋ก ์ ํํด ์ ๊ณตํ๋ค.
์ฌ์ฉ์๋ ๋ก๊ทธ์ธ ๋ฐฉ์ ๋์ ๊ณ์ ๋ง ์ ํํ๋ฉด ๋๋จธ์ง ๊ณผ์ ์ด ์๋์ผ๋ก ์งํ๋๋ฏ๋ก ํธ๋ฆฌํ ๊ฒ์ด๋ค.
๊ฐ์ฅ ๋จผ์ GetCredentialRequest
๋ฅผ ์ธ์คํด์คํ ํ ํ addCredentialOption()
๋ฉ์๋๋ฅผ ์ฌ์ฉํด CredentialOption
์ ์ถ๊ฐํ ์ ์๋ค.
val request = GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build()
CredentialOption
์ Google ์น ์ ํ๋ฆฌ์ผ์ด์
Key๊ฐ์ ๋ฑ๋กํ๊ฑฐ๋ ๋ณด์ ๊ฐํ, ์๋ ๋ก๊ทธ์ธ ๋ฑ์ ์ต์
์ ์ค์ ํ ์ ์๋ค.
val googleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(false)
.setServerClientId(BuildConfig.google_web_key) //Web client td
.setAutoSelectEnabled(false)
.build()
์ฌ์ฉ์ ์ธ์ฆ ์ ๋ณด๋ฅผ ์์ฒญํ๊ธฐ ์ํด์ CredentialManager
๋ฅผ ์์ฑํ๊ณ getCredential()
๋ฉ์๋๋ฅผ ํตํด ์ธ์ฆ์ ์์ฒญํ๋ค.

ํด๋น ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ request์๋ ์์ ๋ง๋ค์๋ GetCredentialRequest
๋ฅผ ๋ฃ์ด์ผ ํ๋ค.
์ด getCredential
ํจ์๋ suspendCancellableCoroutine
์ผ๋ก ์คํ๋๊ธฐ์ ์ฝ๋ฃจํด์ผ๋ก ํธ์ถํด์ผ ํ๋ ๋ฉ์๋์ด๋ค.
suspendCancellableCoroutine
์ ๋ํด์๋ ์๋ ์๋ฌธ์์ ์ ๊น ์ง๊ณ ๋์ด๊ฐ ์์ ์ด๋ค.
๋ง์ฝ ์ API๊ฐ ์ฑ๊ณตํ๋ฉด GoogleIdTokenCredential
๋ฐ์ดํฐ์ ๊ฒฐ๊ณผ๊ฐ ํฌํจ๋ CustomCredential
๋ฅผ ์ถ์ถํ๋ค.
CustomCredential
์ ์ ํ์ GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL
์ ๊ฐ๊ณผ ๊ฐ์์ผ ํ๋ค. GoogleIdTokenCredential.createFrom
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ GoogleIdTokenCredential
๋ก ๋ณํํ๋ค.
๋ง์ฝ ๋ณํ์ ์ฑ๊ณตํ๋ฉด GoogleIdTokenCredential
ID๋ฅผ ์ถ์ถํ๊ณ ๊ฒ์ฆํ ํ ์๋ฒ์์ ์ฌ์ฉ์ ์ธ์ฆ ์ ๋ณด๋ฅผ ์ธ์ฆํ๋ค.
GoogleIdTokenParsingException
๊ณผ ํจ๊ป ๋ณํ์ ์คํจํ๋ฉด Google ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฒ์ ์ ์
๋ฐ์ดํธํด์ผ ํ ์๋ ์๋ค.
val googleIdTokenCredential = GoogleIdTokenCredential
.createFrom(credential.data)
val firebaseCredential = GoogleAuthProvider.getCredential(
googleIdTokenCredential.idToken,
null
)
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ํ ๊ตฌ๊ธ ๊ณ์ ์ Firebase Authentication์ ์ฐ๊ฒฐํ๊ธฐ ์ํ์ฌ FirebaseAuth๋ฅผ ์์ฑํ๊ณ
signInWithCredential()
๋ฉ์๋๋ฅผ ํตํด ์ฐ๊ฒฐํ๋ค.
์ด๋ ํด๋น ์ธ์๋ก ์์์ GoogleAuthProvider.getCredential
๋ฉ์๋๋ฅผ ํตํด ์ถ์ถํ๋ AuthCredential
์ ๋๊ฒจ์ค์ผ ํ๋ค.
auth.signInWithCredential(firebaseCredential)
.addOnCompleteListener { authResult ->
if (authResult.isSuccessful) {
trySend(AuthResponse.Success)
val user = authResult.result.user
user?.let { user ->
Log.d("AuthenticationManager", "${user.email}")
}
} else {
Log.d("AuthenticationManager", "${authResult.exception}")
}
}
FirebaseAuth ์ฝ๋ ์์ฑ ๋ฐฉ๋ฒ์๋ ์๋์ ๊ฐ์ด 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
*private val* auth = FirebaseAuth.getInstance()
*private val* auth = Firebase.*auth*
๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น?
Firebase Authentication ์ด๊ธฐ ๋ฒ์ ๋ถํฐ ์ฌ์ฉ๋์ด ์จ ์ ํต์ ์ธ ๋ฐฉ๋ฒ์ด๋ค.
FirebaseAuth.getInstance()
๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ํด๋น ํ๋ก์ ํธ ๋ด์์ ์ ์ผํ FirebaseAuth
์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ค.
Firebase SDK v9 ๋ฒ์ ๋ถํฐ ๋์ ๋ ์๋ก์ด ๋ฐฉ์์ด๋ค.
Firebase์ ๋ค์ํ ์๋น์ค(Authentication, Realtime Database, Cloud Firestore ๋ฑ)๋ฅผ ํตํฉ์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํ Firebase
๊ฐ์ฒด์ ๋ฐ๋ก ์ ๊ทผํ์ฌ FireAuth
๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ด๋ค.
๐ก ์ฆ, Firebase.auth
๋ฐฉ์์ด ์ต์ ๋ฒ์ ์์ ๋ ๊ฐํธํ๊ฒ ์ฌ์ฉ๋๋ ๋ฐฉ์์ด๋ค.
suspendCancellableCoroutine
๋ ์ฝ๋ฃจํด์์ ๋น๋๊ธฐ ์์
์ ์ํํ ๋, ์์
์ ์ค๋จํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ํนํ suspendCancellableCoroutine
ํจ์๋ ์์
์ด ์ทจ์ ๋ ๋ ์ถ๊ฐ์ ์ธ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ invokOnCancellation api๋ฅผ ์ ๊ณตํ๋ค.
์ฃผ๋ก ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์์คํ ์์ ์ ๊ณตํ๋ ์ฝ๋ฐฑ ๊ธฐ๋ฐ์ ๋น๋๊ธฐ API๋ฅผ ์ฝ๋ฃจํด๊ณผ ํตํฉํ ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋๋ค.
https://firebase.google.com/docs/auth/android/google-signin?hl=ko#kotlin+ktx_1
Firebase Google Authentication ๊ณต์ ๋ฌธ์๋ฅผ ๋ณด๊ณ ๋ฐ๋ผํ๋ ค ํ์ผ๋ ์์ ์ฝ๋ ์ค BegingSignInRequest
๋ถ๋ถ์ด deprecated ๋์๋ค.
BeginSignInRequest
๋์ Credential Manager
๋ฅผ ์ฌ์ฉํ๋ผ๋ ์๋ด ๋ฌธ๊ตฌ๋ฅผ ํตํด ์์ ํ์๋ค.
์ธ์ฆ ๊ด๋ฆฌ์๋ ๋จ์ผ API์์ ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ๋น๋ฐ๋ฒํธ, ํจ์คํค, ์ ํด ๋ก๊ทธ์ธ ์๋ฅ์ (์: Google ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธ)๊ณผ ๊ฐ์ ๋ฉํฐ ๋ก๊ทธ์ธ ๋ฐฉ์์ ์ง์ํ์ฌ ๊ฐ๋ฐ์๋ฅผ ์ํ ํตํฉ์ ๊ฐ์ํํ๋ Jetpack API์ด๋ค.
๋ํ ์ธ์ฆ ๋ฐฉ์ ์ ๋ฐ์์ ๋ก๊ทธ์ธ ์ธํฐํ์ด์ค๋ฅผ ํตํฉํ๋ฏ๋ก ์ฌ์ฉ์๋ ์์ ์ด ์ ํํ ๋ฐฉ์๊ณผ ์๊ด์์ด ๋ ๋ช ํํ๊ณ ์ฝ๊ฒ ์ฑ์ ๋ก๊ทธ์ธํ ์ ์๋ค.
๊ตฌ๊ธ ๋ก๊ทธ์ธ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์คํํ์ง๋ง, ์ฑ์ด ๋ฐ๋ก ์ข ๋ฃ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์
์๋ฌ์ฝ๋๋ ์๋์ ๊ฐ๋ค.

๊ณต์ ๋ฌธ์ ์ฝ๋๋ฅผ ๋ณด๋ฉฐ ๋ฐ๋ผํ๋ ์ค Cannot find a matching credentail
์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
์ด๋ค ๋ฌธ์ ์ธ๊ฐ ๊ฒ์ํ๋ ์ค ๋ต์ ์ฐพ์ ์ ์์๋ค.

๋ฐ๋ผํ ์์ ๊ณต์ ๋ฌธ์ ์ฝ๋ ์ค setFilterByAuthorizedAccounts(true)
๋ถ๋ถ์์ ์๋ฌ๊ฐ ๋ ๊ฒ์ด์๋ค.
ํด๋น ํจ์์ ํ๋ผ๋ฏธํฐ๋ฅผ true ๋ก ์ค์ ํ๋ ๊ฒฝ์ฐ, ์ฑ์ ์ด๋ฏธ ์ธ์ฆ๋, ์ด์ ์ ๋ก๊ทธ์ธํ ๊ตฌ๊ธ ๊ณ์ ๋ง ๋ก๊ทธ์ธํ ์ ์์ด, ํ๋ฒ๋ ์ธ์ฆํ์ง ์์ ๊ฒฝ์ฐ์ ์์ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ด์๋ค.
๋ฐ๋ฉด์, false ๋ก ์ค์ ํ ๊ฒฝ์ฐ, ์๋ก์ด ๊ตฌ๊ธ ๊ณ์ ๋ ์ฑ์ ๋ก๊ทธ์ธํ ์ ์๋๋ก ์ง์ํ ์ ์๋ค.
์ฐธ๊ณ
https://developers.google.com/identity/one-tap/android/get-saved-credentials?hl=ko
์์ setFilterByAuthorizedAccounts
๊ด๋ จ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ํ ์ค์ ๊ตฌ๊ธ ๋ก๊ทธ์ธ ๊ณ์ ์ ์ ํํ๊ณ ๋์ ๋ก๊ทธ์ธ์ด ์งํ๋๋ ๋์ค ์ฑ์ด ์ข
๋ฃ๋๊ณ ์๋์ ๊ฐ์ ์๋ฌ ๋ฉ์ธ์ง๊ฐ ์ถ๋ ฅ๋์๋ค.

์ ์ฐธ๊ณ ์๋ฃ์์ ๋ต์ ์ฐพ์ ์ ์์๋ค.
My findings says that, if we use OAuth Client ID generated using application type Android, then it will not work and generate this exception
์ฆ, GetGoogleIdOption.setServerClientId(key: String)
์์ ํค ๊ฐ์ผ๋ก ์น ์ดํ๋ฆฌ์ผ์ด์
ํค ๊ฐ์ ๋ฃ์ด์ผ ํ๋ค๋ ๊ฒ์ด๋ค.

์ด์ ์๋ Google Cloud Console์ ์ ํ์์ Android ์ ํ์ ํด๋ผ์ด์ธํธ ID๋ฅผ ์ฌ์ฉํ์๋๋ฐ, ์ด๊ฒ์ ์น ์ ํ๋ฆฌ์ผ์ด์ ํด๋ผ์ด์ธํธ ID๋ฅผ ์ฌ์ฉํด์ผํ๋ค๋ ๊ฒ์ด์๋ค.

์ด๋ ๊ณต์๋ฌธ์์๋ ๋์จ ๋ด์ฉ์ด๋ค.
๊ณต์๋ฌธ์๋ฅผ ๊ผผ๊ผผํ ์ฝ์ง ์์๊ธฐ์ ๋ฐ์ํ ๋ฌธ์