【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 授权弹窗,授权成功后也能获取到用户的基本信息,例如 emailopenid 。但在实际 Android 端测试中,无法获取 idToken

根据社区用户的反馈,iOS 端可能可以获取到 idToken,但因为我的项目仅开发 Android 平台,且手头没有 iOS 设备,所以未进行验证。


为什么我们需要 idToken?

在现代应用的身份验证流程中,仅通过 emailopenid 来识别用户并不安全。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 登录体验,希望这篇文章能帮到你 🙌

相关推荐
求梦820几秒前
前端八股文【CSS核心面试题库】
前端·css·面试
算法小菜鸟成长心得1 分钟前
记录自己第一次将React 编写的前端部署到服务器,实现外网访问
服务器·前端·react.js
怒放的生命19911 小时前
pnpm + Monorepo 使用教程(集成 Vue 3 项目)
前端·vue.js·pnpm·monorepo·前端工程化
佛系打工仔6 小时前
绘制K线第二章:背景网格绘制
android·前端·架构
明天好,会的8 小时前
分形生成实验(五):人机协同破局--30万token揭示Actix-web状态管理的微妙边界
运维·服务器·前端
C_心欲无痕8 小时前
nginx - alias 和 root 的区别详解
运维·前端·nginx
我是苏苏10 小时前
Web开发:C#通过ProcessStartInfo动态调用执行Python脚本
java·服务器·前端
无羡仙11 小时前
Vue插槽
前端·vue.js
用户63879947730511 小时前
每组件(Per-Component)与集中式(Centralized)i18n
前端·javascript