You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin使用Google Credential Manager获取AccessToken求助

解决Android CredentialManager获取Google登录Access Token的问题

核心问题

你当前的CredentialManager配置仅请求了Google ID Token,因此无法获取Access Token。需要调整请求参数,明确要求获取Access Token,并解析对应的凭证类型。

解决方案步骤

1. 调整CredentialManager请求配置

在构建GetCredentialRequest时,通过GoogleIdTokenOption开启Access Token请求,并指定所需的OAuth2权限范围:

// 替换为你的Web客户端ID(在Google Cloud控制台获取,不是Android客户端ID)
const val WEB_CLIENT_ID = "your-web-client-id.apps.googleusercontent.com"

val googleIdTokenOption = GoogleIdTokenOption.Builder()
    .setFilterByAuthorizedAccounts(false)
    .setServerClientId(WEB_CLIENT_ID)
    .requestAccessToken(true) // 关键:开启Access Token请求
    .setScopes(listOf("https://www.googleapis.com/auth/userinfo.profile")) // 根据需求添加权限范围
    .build()

val getCredentialRequest = GetCredentialRequest.Builder()
    .addCredentialOption(googleIdTokenOption)
    .build()

2. 解析包含Access Token的凭证

当获取到Credential后,判断其类型为OAuth2Credential.TYPE_OAUTH2_CREDENTIAL,从中提取Access Token:

credentialManager.getCredential(context, getCredentialRequest)
    .addOnSuccessListener { result ->
        val credential = result.credential
        when (credential.type) {
            OAuth2Credential.TYPE_OAUTH2_CREDENTIAL -> {
                try {
                    val oAuth2Credential = OAuth2Credential.createFrom(credential.data)
                    val accessToken = oAuth2Credential.accessToken
                    val idToken = oAuth2Credential.idToken // 如果需要也能拿到ID Token
                    // 在这里将accessToken发送到服务器进行认证
                } catch (e: Exception) {
                    Log.d("pikaboo", "解析OAuth2凭证失败", e)
                }
            }
            GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL -> {
                // 原来的ID Token处理逻辑(可选保留)
                try {
                    val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)
                    val idToken = googleIdTokenCredential.idToken
                    // ... 其他信息处理
                } catch (e: GoogleIdTokenParsingException) {
                    Log.d("pikaboo", "Received an invalid google id token response", e)
                }
            }
        }
    }
    .addOnFailureListener { e ->
        Log.d("pikaboo", "获取凭证失败", e)
    }

3. 注意事项

  • Web客户端ID:必须使用Google Cloud控制台中创建的Web应用客户端ID,而非Android客户端ID——Access Token的验证需要结合Client Secret,仅Web客户端配置有该参数。
  • 权限范围:根据业务需求添加合适的OAuth2范围,比如需要获取用户邮箱可添加"https://www.googleapis.com/auth/userinfo.email"。
  • Google Cloud配置:确保项目已启用Google Identity API,且Android客户端和Web客户端ID的OAuth2权限配置正确。

备选方案(若CredentialManager无法满足需求)

若上述方法仍无法获取Access Token,可结合Google Sign-In SDK(旧版但稳定)实现:

val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
    .requestIdToken(WEB_CLIENT_ID)
    .requestAccessToken()
    .requestScopes(Scope("https://www.googleapis.com/auth/userinfo.profile"))
    .build()

val googleSignInClient = GoogleSignIn.getClient(context, googleSignInOptions)

// 启动登录流程
startActivityForResult(googleSignInClient.signInIntent, RC_SIGN_IN)

// 在onActivityResult中处理结果
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == RC_SIGN_IN) {
        val task = GoogleSignIn.getSignedInAccountFromIntent(data)
        try {
            val account = task.getResult(ApiException::class.java)
            val accessToken = account.accessToken
            // 发送accessToken到服务器
        } catch (e: ApiException) {
            Log.d("pikaboo", "登录失败", e)
        }
    }
}

内容的提问来源于stack exchange,提问作者mostafa hashim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 01:15:59