【谷歌登录SDK集成】
这里整理总结一下,谷歌登录的大概流程:
其实我们不用去搜索其他文章,直接看 官方文档 就行,官方文档写的还是挺详细的。
这里整理一下大致流程,方便日后查看:
注意:目前官方有旧版和新版,旧版已经废弃了,直接忽略吧!
一:声明依赖项
//google 登录 https://developer.android.google.cn/identity/sign-in/credential-manager-siwg?hl=zh-cnimplementation("androidx.credentials:credentials:1.3.0")implementation("androidx.credentials:credentials-play-services-auth:1.3.0")implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1"// 如果使用 Firebase Authentication(可选)//implementation 'com.google.firebase:firebase-auth:22.1.1'
二:具体步骤
/***实例化 Google 登录请求**/private fun initGoogleLogin() {credentialManager = CredentialManager.create(this)mGetGoogleIdOption = GetGoogleIdOption.Builder().setFilterByAuthorizedAccounts(true).setServerClientId(Configure.WEB_CLIENT_ID).setAutoSelectEnabled(true).build()}
/*** 发起登录请求*/private fun sendGoogleLogin() {val request: GetCredentialRequest = GetCredentialRequest.Builder().addCredentialOption(mGetGoogleIdOption!!).build()lifecycleScope.launch {try {val result = credentialManager?.getCredential(request = request,context = this@LoginActivity,)result?.let {handleSignInResult(it)}// credentialManager?.clearCredentialState()} catch (e: GetCredentialException) {e.printStackTrace()Log.i(TAG, "handleSignInResult: GetCredential Exception:${e.message}")Toaster.showLong("${e.message}")}}}
/*** {"zab":0,"zac":[{"zza":1,"zzb":"https://www.googleapis.com/auth/userinfo.profile"},{"zza":1,"zzb":"https://www.googleapis.com/auth/userinfo.email"},{"zza":1,"zzb":"openid"},{"zza":1,"zzb":"email"},{"zza":1,"zzb":"profile"}],"zad":"114628040420895063026","zae":null,"zaf":"ypkmail.com@gmail.com","zag":"大草原水","zah":{},"zai":null,"zaj":1749785106,"zak":"480E04697BE81401762ED71350BAD92D","zal":"草原水","zam":"大","zan":[]}* 处理成功返回的凭据。** 实例化 GetCredentialRequest,然后使用 addCredentialOption() 添加之前创建的 googleIdOption 以检索凭据。* 将此请求传递给 getCredential() (Kotlin) 或 getCredentialAsync() (Java) 调用以检索用户的可用凭据。* API 成功运行后,提取存放 GoogleIdTokenCredential 数据结果的 CustomCredential。* CustomCredential 的类型应等于 GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL 的值。使用 GoogleIdTokenCredential.createFrom 方法将该对象转换为 GoogleIdTokenCredential。* 如果转换成功,请提取 GoogleIdTokenCredential ID,对其进行验证,并在服务器上对凭据进行身份验证。** 如果转换失败并显示 GoogleIdTokenParsingException,那么您可能需要更新“使用 Google 账号登录”库的版本。** 捕获任何无法识别的自定义凭据类型。**/private fun handleSignInResult(result: GetCredentialResponse) {val credential = result.credentialwhen (credential) {// Passkey credential (密钥凭据)is PublicKeyCredential -> {//在服务器上共享responseJson (如GetCredentialResponse) 以验证和身份验证val responseJson = credential.authenticationResponseJsonLog.i(TAG, "handleSignInResult: responseJson=$responseJson")}// Password credential(密码凭据)is PasswordCredential -> {// 将ID和密码发送到服务器以进行验证和身份验证。val username = credential.idval password = credential.passwordLog.i(TAG, "handleSignInResult: username=$username password=$password")}// GoogleIdToken credential(GoogleIdToken凭据)is CustomCredential -> {if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {try {// 使用googleidtokential并提取ID以在服务器上进行验证和身份验证。val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)// You can use the members of googleIdTokenCredential directly for UX purposes, but don't use them to store or control access to user data. For that you first need to validate the token:pass googleIdTokenCredential.getIdToken() to the backend server.//您可以将 googleidtokential 的成员直接用于UX目的,但不要使用它们来存储或控制对用户数据的访问。为此,您首先需要验证令牌: 将googleidtokential.getIdToken() 传递给后端服务器。loginGoogleDealWith(googleIdTokenCredential)//GoogleIdTokenVerifier verifier = ... // see validation instructions// GoogleIdToken idToken = verifier.verify(idTokenString);// To get a stable account identifier (e.g. for storing user data),use the subject ID: idToken.getPayload().getSubject()//要获取稳定的帐户标识符 (例如用于存储用户数据),请使用主题ID: idToken.getPayload().getSubject()} catch (e: GoogleIdTokenParsingException) {e.printStackTrace()Log.e(TAG, "Received an invalid google id token response", e)}} else {Log.e(TAG, "else google login Unexpected type of credential(在此处捕获任何无法识别的凭据类型。)")}}else -> {Log.e(TAG, "google login Unexpected type of credential(在此处捕获任何无法识别的凭据类型。)")}}}
最后拿到结果,获取处理:
private fun loginGoogleDealWith(googleIdTokenCredential: GoogleIdTokenCredential) {Log.i(TAG, "handleSignInResult: account=${GsonUtils.toJson(googleIdTokenCredential)}")googleIdTokenCredential?.let {Log.i(TAG,"handleSignInResult: " +//"email=${it.email} " +"displayName=${it.displayName} " +"idToken=${it.idToken} " +"phoneNumber=${it.phoneNumber} " +"photoUrl=${it.profilePictureUri} " +"familyName=${it.familyName} " +"id=${it.id}")val strEmail=it.id}}
三: 使用 Firebase 认证(可选)
private fun firebaseAuthWithGoogle(idToken: String) {val credential = GoogleAuthProvider.getCredential(idToken, null)FirebaseAuth.getInstance().signInWithCredential(credential).addOnCompleteListener { task ->if (task.isSuccessful) {val user = FirebaseAuth.getInstance().currentUserLog.d("FirebaseAuth", "Login success: ${user?.email}")} else {Log.w("FirebaseAuth", "Login failed", task.exception)}}
}
四: 注意事项
- Web Client ID 必须使用 OAuth 2.0 的“Web 应用”类型客户端 ID,而不是 Android 客户端 ID
- Credential Manager 不再使用旧的 GoogleSignInClient 和 onActivityResult()
- 多账户支持 你可以设置 .setFilterByAuthorizedAccounts(true) 以限定已授权用户
五:流程图
[用户点击登录按钮]
↓
[调用 CredentialManager.getCredential()]
↓
[返回 GoogleIdTokenCredential]
↓
[提取 ID Token / 用户信息]
↓
[(可选)Firebase Auth 认证]
参考文章:
官方文档
Android集成Google登录