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

相关推荐
2501_944525541 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
李白你好2 小时前
Burp Suite插件用于自动检测Web应用程序中的未授权访问漏洞
前端
刘一说3 小时前
Vue 组件不必要的重新渲染问题解析:为什么子组件总在“无故”刷新?
前端·javascript·vue.js
徐同保4 小时前
React useRef 完全指南:在异步回调中访问最新的 props/state引言
前端·javascript·react.js
刘一说4 小时前
Vue 导航守卫未生效问题解析:为什么路由守卫不执行或逻辑失效?
前端·javascript·vue.js
一周七喜h5 小时前
在Vue3和TypeScripts中使用pinia
前端·javascript·vue.js
weixin_395448915 小时前
main.c_cursor_0202
前端·网络·算法
东东5165 小时前
基于vue的电商购物网站vue +ssm
java·前端·javascript·vue.js·毕业设计·毕设
MediaTea6 小时前
<span class=“js_title_inner“>Python:实例对象</span>
开发语言·前端·javascript·python·ecmascript
梦梦代码精6 小时前
开源、免费、可商用:BuildingAI一站式体验报告
开发语言·前端·数据结构·人工智能·后端·开源·知识图谱