Android Kotlin:谷歌Credential Manager获取用户ID返回邮箱问题求助
关于Google Credential Manager获取用户ID的问题
问题场景
使用新版Google Credential Manager时,发现调用googleIdTokenCredential.id返回的是用户邮箱,而旧版Google Sign In的acct.id返回的是类似113755066377078777777的数字用户ID。现有大量用户已关联该数字ID,因此需要明确两个问题:
- 新版API返回邮箱是否属于bug?
- 如何通过新版Credential Manager获取旧版格式的数字用户ID?
新版Credential Manager代码
if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) { try { val googleIdTokenCredential = GoogleIdTokenCredential .createFrom(credential.data) val personToken = googleIdTokenCredential.idToken val personId = googleIdTokenCredential.id // 此处返回邮箱 val displayName = googleIdTokenCredential.displayName val personPhoto = googleIdTokenCredential.profilePictureUri } catch (e: GoogleIdTokenParsingException) { Log.d("pikaboo", "Received an invalid google id token response", e) } }
旧版Google Sign In代码
val acct = GoogleSignIn.getLastSignedInAccount(this@GoogleLogin) if (acct != null) { val displayName = acct.displayName val personGivenName = acct.givenName val personFamilyName = acct.familyName val personId = acct.id // 此处返回数字用户ID val personPhoto = acct.photoUrl var photo = "" if(personPhoto != null){ photo = personPhoto.toString() } sendToServer(personId!!, photo, displayName, personGivenName, personFamilyName) }
问题解答
1. googleIdTokenCredential.id返回邮箱是否是bug?
这不是bug,是API设计的差异。旧版Google Sign In的acct.id对应ID Token中的sub字段(用户唯一数字标识),而新版Credential Manager的GoogleIdTokenCredential.id默认返回的是ID Token中的email字段。两者只是API封装时选择暴露的字段不同,并非功能异常。
2. 获取旧版格式的数字用户ID的方法
要拿到和旧版acct.id一致的数字用户ID,需要直接解析ID Token中的sub字段。具体步骤如下:
- 获取完整的ID Token字符串(即
googleIdTokenCredential.idToken) - 解析该JWT Token,提取
sub字段的值,这就是所需的数字用户ID。
示例代码如下:
import com.google.android.gms.auth.api.identity.GoogleIdToken import com.google.android.gms.auth.api.identity.GoogleIdTokenCredential if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) { try { val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data) val idToken = googleIdTokenCredential.idToken // 解析ID Token获取sub字段(对应旧版acct.id) val googleIdToken = GoogleIdToken.parse(idToken) val payload = googleIdToken.payload val personId = payload.subject // 此处返回数字用户ID // 其他字段获取保持不变 val displayName = googleIdTokenCredential.displayName val personPhoto = googleIdTokenCredential.profilePictureUri // 后续逻辑:关联现有用户数据等 // sendToServer(personId, ...) } catch (e: GoogleIdTokenParsingException) { Log.d("pikaboo", "Received an invalid google id token response", e) } catch (e: IllegalArgumentException) { Log.d("pikaboo", "Failed to parse ID token", e) } }
payload.subject的值和旧版acct.id完全一致,可以直接用于关联现有用户的历史数据。
内容的提问来源于stack exchange,提问作者TheGreatCornholio
相关产品推荐
相关产品推荐

