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

相关推荐
elangyipi1234 分钟前
深入理解前端项目中的 package.json 和 package-lock.json
前端·json
LYFlied16 分钟前
【算法解题模板】-【回溯】----“试错式”问题解决利器
前端·数据结构·算法·leetcode·面试·职场和发展
composurext17 分钟前
录音切片上传
前端·javascript·css
程序员小寒17 分钟前
前端高频面试题:深拷贝和浅拷贝的区别?
前端·javascript·面试
狮子座的男孩22 分钟前
html+css基础:07、css2的复合选择器_伪类选择器(概念、动态伪类、结构伪类(核心)、否定伪类、UI伪类、目标伪类、语言伪类)及伪元素选择器
前端·css·经验分享·html·伪类选择器·伪元素选择器·结构伪类
zhougl99623 分钟前
Vue 中的 `render` 函数
前端·javascript·vue.js
听风吟丶24 分钟前
Spring Boot 自动配置深度解析:原理、实战与源码追踪
前端·bootstrap·html
跟着珅聪学java25 分钟前
HTML中设置<select>下拉框默认值的详细教程
开发语言·前端·javascript
IT_陈寒25 分钟前
JavaScript 性能优化:5个被低估的V8引擎技巧让你的代码提速50%
前端·人工智能·后端
想睡好31 分钟前
setup
前端·javascript·html