AnEricn
AnEricn
  • 发布:2026-11-13 10:44
  • 更新:2026-11-13 10:45
  • 阅读:22

【报Bug】App-Android 端 uni.login({ provider: 'google' }) 只返回 openid / unionid,拿不到 id_token,服务端无法核验登录身份

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Mac

PC开发环境操作系统版本号: macOS 26.4.1

HBuilderX类型: 正式

HBuilderX版本号: 5.34

手机系统: Android

手机系统版本号: Android 16

手机厂商: vivo

手机机型: vivo V2608A

页面类型: vue

vue版本: vue3

打包方式: 云端

项目创建方式: HBuilderX

操作步骤:

复现步骤

  1. manifest.json 的 App 模块配置里勾选 OAuth → Google 登录,按文档填写 iOS 平台客户端 ID(文档写明“Android平台不需要客户端ID”)。
  2. 在 Google Cloud 控制台为 Android 包名和签名证书 SHA-1 创建 OAuth 客户端。
  3. 云端打包自定义调试基座,安装到 Android 真机。
  4. 执行下面的代码,选择一个 Google 账号完成登录。
uni.login({  
  provider: 'google',  
  success: (res) => {  
    console.log('authResult 字段:', Object.keys(res.authResult || {}))  
    uni.getUserInfo({  
      provider: 'google',  
      success: (info) => {  
        console.log('userInfo 字段:', Object.keys(info.userInfo || {}))  
      }  
    })  
  },  
  fail: (err) => console.log('登录失败:', err)  
})

预期结果:

authResult 中包含 Google 签发的 ID token(例如 id_token 字段),可提交给服务端核验。

实际结果:

实际结果

来源 Android 实际返回的字段
uni.login 的 authResult openid、unionid
uni.getUserInfo 的 userInfo nickname、unionid、openid、email、openId、nickName、avatarUrl

两处都没有任何令牌或授权码。

原因推测

Google 在 Android 上只有在发起登录时传入“服务端 client id”(Web 应用类型的 OAuth 客户端 ID)才会签发 ID token。内置模块在 Android 端不需要也无法配置 client id,因此推测登录请求里没有带这个参数,Google 只返回了账号基本信息。

希望官方支持

  1. Android 端的 Google 登录支持配置服务端 client id(Web client id),可以放在 manifest.json 里,或作为 uni.login 的参数传入。
  2. 登录成功后在 authResult 中返回 id_token,字段名与 iOS 端保持一致。
  3. 在 Google 登录文档中补充 authResult 的字段说明,以及 Android 与 iOS 的差异。目前文档没有列出任何返回字段。

bug描述:

问题描述

Android 端使用内置的 Google 登录模块,登录成功后返回的数据里只有 openid 和 unionid,没有 id_token、access_token 或授权码。

服务端要确认“这次登录确实是该 Google 账号本人发起的”,必须拿到 Google 签发的 ID token 去核验。只有 openid 的话,任何人只要知道某个用户的 openid 就能伪造登录请求,存在账号冒用风险。目前 Android 端无法用内置模块实现安全的 Google 登录。

同一份代码在 iOS 端可以拿到能通过服务端核验的令牌,只有 Android 端缺失。

实际造成的安全问题

这个缺失已经在我们的线上环境造成了安全事故,过程如下。

  1. 客户端只能提交 openid:Android 端拿不到任何令牌,登录时只能把 openid 发给服务端,作为“这个用户已通过 Google 登录”的依据。
  2. 服务端被迫信任 openid:Android 端没有可核验的凭据,服务端只能为它保留一条“只凭 openid 就放行”的兼容路径,否则所有 Android 用户都无法用 Google 登录。
  3. openid 不是秘密:它是 Google 账号的固定标识,不会过期、不会变化,也不是只有用户本人才知道。它会出现在客户端日志、抓包数据和其他接入了 Google 登录的应用里。
  4. 攻击方式:攻击者不需要打开 App,也不需要经过 Google 授权。直接向登录接口发送一条请求,带上目标用户的 openid,服务端就会当作该用户登录成功并签发登录态。同样的方式也可以用任意编造的 openid 批量注册账号。
  5. 后果:已绑定 Google 登录的账号可以被他人冒用,攻击者登录后拥有该账号的全部权限。

问题的关键在于:服务端无法区分“真正通过 Google 授权的 Android 用户”和“直接伪造请求的攻击者”,因为两者提交的内容完全一样,都只有 openid。只要 Android 端拿不到 Google 签发的令牌,这条不安全的路径就无法关闭。

我们目前的处理是服务端停止接受只有 openid 的请求,同时自行编写原生插件获取 ID token。代价是所有旧版本 Android 用户在升级前都无法使用 Google 登录。

2026-11-13 10:44 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

欢迎到专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。

感谢这份 bug 反馈,整体质量很高。下面以官方评审视角,从反馈完整性和问题成立性两方面进行说明。

一、反馈完整性评审

  • BUG 标题:清晰准确,直接点明了“Android 端 Google 登录缺少 id_token、服务端无法核验”这一核心问题。
  • BUG 描述:非常详细,除现象外还给出了完整的安全影响链路(openid 非秘密 → 可伪造请求 → 账号冒用)、线上事故过程和原因推测,官方人员可以直接理解问题背景与严重性,无需额外澄清。
  • 代码示例:完整可直接运行,采用的就是官方文档示例代码,无需调整。
  • 复现步骤:清晰完整,覆盖了 manifest 配置、Google Cloud 控制台 Android OAuth 客户端创建、云端打包自定义调试基座、真机执行全流程,按步骤可复现。
  • 预期结果:合理。Google 官方 Android 登录体系本身支持通过服务端 client id(Web client id)签发 ID token,且 iOS 端内置模块已返回令牌,期望 Android 端对齐并返回 id_token 是合理诉求,并非过度要求。
  • 实际结果:以表格列出了 authResult 与 userInfo 的具体字段,便于核对,不是误报。
  • 分类信息:完整,包含操作系统及版本、HBuilderX 类型与版本号、手机系统、Vue 版本、厂商与机型、打包方式等。
  • 另外说明:我无法识别附件,本反馈以文字描述为主,现有信息已足够评审。

二、bug 是否成立

结论:该问题成立,属于内置 Google 登录模块在 Android 端的已知能力差异,不是误报。依据如下:

  1. 官方文档层面:Google 登录文档的配置部分仅提供“iOS平台客户端ID”配置项,并注明“Android平台不需要客户端ID”(配置文档);uni.login 的 success 返回参数说明 中 authResult 仅描述为“登录服务商提供的登录信息,服务商不同返回的结果不完全相同”,未列出 Google 平台各端的具体返回字段。文档现状与您的描述一致。
  2. 社区已有同类反馈:
  3. 您推测的机制(Android 端发起登录时未传服务端 client id,导致 Google 不签发 ID token)与上述社区验证结论吻合,推测合理。

三、替代方案建议

在官方内置模块补齐该能力之前,可参考以下方案:

  1. 官方 uni_modules 插件 uni-oauth-google(Google登录插件):由 DCloud 移动团队出品,基于 Android Credential Manager 实现,调用时传入 serverClientId(即 Web 应用类型的 OAuth 客户端 ID),与您推测的机制一致;适用于 uni-app(HBuilderX 4.75+)Vue2/Vue3 项目、Android 5.0+,需以正确的包名和证书打自定义基座,具体返回字段请以插件详情页说明为准。
  2. 插件市场第三方插件 wen-GoogleSignin:支持 Android/iOS 双端,登录成功返回 idToken(JWT)可用于后端验签建立会话,支持 uni-app 与 uni-app x(HBuilderX 4.66+),并要求 App 内填写 Web 应用 OAuth Client ID。
  3. 社区验证过的临时方案:通过 plus.android 原生调用 GoogleSignIn API,在 requestIdToken / requestServerAuthCode 中传入 Web client id,可直接拿到 id_token 和授权码,详见 ask 178260 的回复。您目前自行编写原生插件的做法与该思路一致,如自研插件维护成本较高,可评估上述现成插件。

四、文档与产品建议

您提出的三点希望(Android 端支持配置 Web client id、authResult 返回 id_token 且字段名与 iOS 对齐、文档补充返回字段说明及平台差异)均合理,尤其是文档目前确实未列出 Google 登录 authResult 的任何返回字段,这一点会随本次评审一并反馈。

如需持续跟进该问题,建议在 ask 社区 相关帖子下补充您的测试信息(HBuilderX 5.34、Android 16、vivo V2608A),以便官方汇总各版本复现情况。

内容为 AI 生成,仅供参考

要回复问题请先登录或注册