在开发 uni-app Android 应用的过程中,若计划出海发布,接入 Google 登录是一个非常常见的需求。uni-app 官方提供了基础的 Google 登录方案:官方文档地址。
以下是官方提供的代码示例:
php
const handleGoogleLogin = () => {
// 谷歌登录配置
uni.login({
provider: 'google',
success: function (loginRes) {
uni.showModal({
title: 'Google 登录信息1',
content: JSON.stringify(loginRes),
success: () => {
// 登录成功后获取用户信息
uni.getUserInfo({
provider: 'google',
success: function (info) {
uni.showModal({
title: 'Google 登录信息2',
content: JSON.stringify(info),
success: () => {
// 登录逻辑
}
})
}
})
}
})
},
fail: function (err) {
console.log('登录失败:', err)
uni.showModal({
title: 'Google 登录失败',
content: JSON.stringify(err)
})
}
})
}
该方案可以正常拉起 Google 授权弹窗,授权成功后也能获取到用户的基本信息,例如 email 和 openid 。但在实际 Android 端测试中,无法获取 idToken。
根据社区用户的反馈,iOS 端可能可以获取到 idToken,但因为我的项目仅开发 Android 平台,且手头没有 iOS 设备,所以未进行验证。
为什么我们需要 idToken?
在现代应用的身份验证流程中,仅通过 email
或 openid
来识别用户并不安全。idToken 才是 Google 授权登录的核心凭证,可用于与服务端进行用户身份校验。
在我的 Web 项目中,Google 登录验证就是依赖 idToken 实现的。所以我想在 App 中也获取到它。
正确姿势:手动接入 Google Sign-In SDK 获取 idToken(Android 专用)
在查阅 DCloud 社区帖子 后,我找到了可行方案,并在实际项目中成功验证。以下是我封装的 Google 登录方法,仅适用于 Android,如果你的项目也使用自定义安卓基座,还需要在基座项目中引入谷歌服务,参考链接
scss
googleSignIn(callback) {
try {
const mainActivity = plus.android.runtimeMainActivity()
const GoogleSignInOptions = plus.android.importClass('com.google.android.gms.auth.api.signin.GoogleSignInOptions')
const gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(GOOGLE_CLIENT_ID) // 关键:申请 idToken
.requestServerAuthCode(GOOGLE_CLIENT_ID)
.requestEmail()
.requestProfile()
.build()
const GoogleSignIn = plus.android.importClass('com.google.android.gms.auth.api.signin.GoogleSignIn')
const mGoogleClient = GoogleSignIn.getClient(mainActivity, gso)
const signInIntent = plus.android.invoke(mGoogleClient, 'getSignInIntent')
const CODE_REQUEST = 200
mainActivity.startActivityForResult(signInIntent, CODE_REQUEST)
mainActivity.onActivityResult = (requestCode, resultCode, data) => {
if (requestCode == CODE_REQUEST) {
const account = new GoogleSignIn().getLastSignedInAccount(mainActivity)
const googleAccountInfo = {
openid: plus.android.invoke(account, 'getId'),
email: plus.android.invoke(account, 'getEmail'),
displayName: plus.android.invoke(account, 'getDisplayName'),
idToken: plus.android.invoke(account, 'getIdToken'), // 目标字段
serverAuthCode: plus.android.invoke(account, 'getServerAuthCode'),
photoUrl: plus.android.invoke(account, 'getPhotoUrl')
}
callback(googleAccountInfo)
} else {
console.error('Google 登录失败', { requestCode, resultCode, data })
}
}
} catch (error) {
console.error('Google 登录异常', error)
}
}
调用方式如下:
javascript
const handleGoogleLogin = () => {
googleServiceStore.googleSignIn(googleAccountInfo => {
if (!googleAccountInfo.idToken) {
console.warn('未获取到 idToken,登录终止')
return
}
// 登录逻辑:将 idToken 发给服务端验证
})
}
如何配置 Google 凭据?
要使上述代码正常工作,你需要在 Google Cloud Console 配置两个客户端凭据:
1. Web 应用凭据(用于请求 idToken)
在代码中,GOOGLE_CLIENT_ID
填写的是 Web 应用类型的客户端 ID ,即用于 .requestIdToken()
方法中。
2. Android 应用凭据(用于确保 App 授权合法)
必须在 Google 控制台中添加一个 Android 应用凭据,绑定你的 App 包名与签名指纹,否则授权流程可能失败或无法正常获取用户信息。
⚠️ 注意:Android 应用的包名和 SHA1 签名要与你实际开发应用保持一致。
如下图所示,两个凭据都需要正确配置:
总结
- uni.login + uni.getUserInfo 无法在 Android 获取 idToken。
- 正确方式是通过 原生 Google Sign-In SDK 获取。
- 核心字段是
idToken
,用于后端身份验证。 - 确保正确配置 Google 控制台中的 Web 应用 与 Android 应用 凭据。
如果你同样在做出海项目,且需要安全可靠的 Google 登录体验,希望这篇文章能帮到你 🙌