【uniapp】uniapp开发安卓应用接入谷歌登录获取idtoken

在开发 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 登录体验,希望这篇文章能帮到你 🙌

相关推荐
陈随易5 小时前
bm2,Node.js 与 Bun 项目部署新选择
前端·后端·程序员
福兮说6 小时前
canvas 旋转图片的六个坑:四角被裁、Math.ceil 多出 1px 黑边、JPG 角发黑、翻转方向反了
前端·javascript·图像处理·canvas
传人once8 小时前
多图片上传预览功能如何写
前端·css·html·jquery·html5
Eric.468 小时前
Wan‑Animate+MiniMax-H3 本地部署 AI 漫剧流水线:8G 显存动作迁移与动态分镜工程实战
前端·人工智能·comfyui·ai漫剧
库拉镜像AI牛牛10 小时前
短剧内容自动化生产:知漫剧工作室落地教程
大数据·服务器·前端·人工智能·语音识别
律宏阔10 小时前
Flutter 列表图片内存优化:CachedNetworkImage 与 ClipRRect 的取舍
前端·flutter
行者全栈架构师10 小时前
【鸿蒙心迹】相册文搜图工程化落地:HarmonyOS 7.0 端侧 AI 检索全链路实战与 5 个踩坑解法
前端
律宏阔10 小时前
Dart 3 Record:解决 Future.wait 异构返回值的类型问题
前端·flutter
Seraphina3610 小时前
DVWA(XSS Reflected/Stored High,CSRF Low)
前端·xss·csrf
默_笙11 小时前
🍔 中间件不只是打日志:四个钩子、一次短路,和自带的工具
前端·javascript