从GoogleSignIn迁移至Credential Manager:如何静默获取idToken
从GoogleSignIn迁移至Credential Manager:如何静默获取idToken
嘿,我完全明白你现在的需求——从GoogleSignIn迁移到Credential Manager,核心就是要替代原来的silentSignIn(),静默拿到idToken给自家服务器发请求对吧?咱们一步步把这个逻辑转过去,保证和你原来的行为一致。
首先先回顾下你原来的GoogleSignIn实现逻辑,方便咱们对应着迁移:
原GoogleSignIn实现
你之前是通过silentSignIn()来静默获取已登录用户的idToken,相关代码大概是这样的:
静默获取idToken的核心代码
val googleSignInClient = GoogleSignIn.getClient( context, GoogleApiClientHelper.generateGoogleSignInOptions() ) val silentSignIn = googleSignInClient.silentSignIn() if (!silentSignIn.isSuccessful || silentSignIn.result.isExpired) { throw IllegalStateException("Could not receive idToken") } val idToken = silentSignIn.result.idToken put("Authorization", "Bearer $idToken")
对应的GoogleSignInOptions配置
fun generateGoogleSignInOptions(account: Account? = null): GoogleSignInOptions { val builder = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) builder.requestScopes(Scope(Constants.SCOPE_MAIL_GOOGLE_COM)) builder.requestEmail() builder.requestIdToken(SERVER_CLIENT_ID) // 补全你截断的账户设置逻辑 account?.let { builder.setAccount(it) } return builder.build() }
迁移到Credential Manager的实现
现在咱们来把上面的逻辑转成Credential Manager的写法,核心是用Credential Manager的无交互获取已有凭证能力,替代原来的静默登录:
1. 引入Credential Manager依赖
先在模块级build.gradle.kts(或build.gradle)里加上依赖:
dependencies { implementation("androidx.credentials:credentials:1.2.2") implementation("androidx.credentials:credentials-play-services-auth:1.2.2") }
2. 初始化Credential Manager
val credentialManager = CredentialManager.create(context)
3. 构建静默获取Google idToken的请求
这里要严格对应你原来的配置:Scope、邮箱请求、Server Client ID一个都不能少,还要开启“只过滤已授权账户”来实现静默效果:
// 构建Google ID凭证请求,完全对齐原配置 val googleIdOption = GetGoogleIdOption.Builder() .setFilterByAuthorizedAccounts(true) // 核心:只返回已授权的账户,实现静默无交互 .setServerClientId(SERVER_CLIENT_ID) .requestScopes(Scope(Constants.SCOPE_MAIL_GOOGLE_COM)) .requestEmail() // 如果需要指定特定账户,加上这行:.setAccountName(account?.name) .build() val request = GetCredentialRequest.Builder() .addCredentialOption(googleIdOption) .build()
4. 静默获取idToken并处理结果
建议用协程来执行异步逻辑,和你原来的同步逻辑体验对齐:
// 放在协程作用域里执行,比如lifecycleScope lifecycleScope.launch { try { val result = credentialManager.getCredential( context = context, request = request ) // 解析拿到idToken val googleIdCredential = result.credential as GoogleIdCredential val idToken = googleIdCredential.idToken // 像原来那样设置请求头即可 put("Authorization", "Bearer $idToken") } catch (e: GetCredentialException) { // 处理各种失败场景,对应原来的isSuccessful判断 when (e) { is NoCredentialException -> { throw IllegalStateException("No authorized Google account found") } is CredentialProviderException -> { throw IllegalStateException("Failed to get credential: ${e.message}") } else -> { throw e } } } }
关键注意点
setFilterByAuthorizedAccounts(true)是实现静默的核心,千万别漏,否则会弹出登录界面- 如果你原来的逻辑支持指定特定账户,直接在
GetGoogleIdOption里调用setAccountName()就行 - 所有原GoogleSignInOptions里的配置,都要在
GetGoogleIdOption里对应设置,保证权限和行为完全一致
这样就完成了迁移,逻辑和你原来的GoogleSignIn静默获取idToken完全对齐,只是换了新的API而已。
备注:内容来源于stack exchange,提问作者Den
相关产品推荐
相关产品推荐

