更新记录

1.1.0(2026-06-17)

初始版本,扩展 API、JWT 解析、状态查询、自动降级完善


平台兼容性

uni-app(4.66)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - - - ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(4.66)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - 5.0 12 × -

wen-GoogleSignin

Google 授权登录插件,为 uni-app / uni-app x 提供原生 Google Sign-In 集成。Android 基于 Credential Manager + Google Identity,iOS 基于 Google Sign-In SDK,支持多种登录、静默登录、登出、idToken 解析、状态查询、自动降级与 Play 服务检测。


平台兼容性

uni-app (4.66)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
5.0+ 12+

uni-app x (4.66)

Chrome Safari Android iOS
5.0+ 12+

导入 uni_modules 规范插件需使用 HBuilderX 4.66+


关于插件

本插件为 uni-app / uni-app x 提供 Google 登录能力,登录成功返回 idToken(JWT),可用于后端验签建立用户会话。

  • 支持 标准登录静默登录Google 按钮登录 三种流程
  • 无凭据时自动降级、静默优先缓存
  • 解析 idToken,获取 subemail_verifiedhd 等字段
  • 提供登录状态查询、Play 服务检测(Android)、登出 / 撤销

SDK 版本信息

平台 版本 支持状态
Android Credential Manager 1.3.0 + Google Identity 1.1.1 ✅ 完全支持
iOS Google Sign-In SDK ✅ 完全支持
功能 Android iOS
Google 登录
静默登录
Google 退出登录
Play 服务检测

重要提示

  • 必须使用自定义基座运行,标准基座不包含原生插件
  • Android:确保设备已安装 Google Play 服务(GMS)
  • Android:应用签名 SHA-1、包名须与 Google Cloud Console 中 Android OAuth 客户端一致
  • iOS:须在插件 Info.plist 中配置 GIDClientID 与 URL Scheme
  • App 内填写的 Client ID 为 Web 应用 OAuth Client ID,不是 Android / iOS Client ID
  • 客户端 parseIdToken / user.id 不可单独用于安全决策,idToken 必须发往后端验签

环境配置

前置条件

  1. Google Cloud Console 创建项目
  2. 启用 Google Sign-In / Identity 相关 API
  3. 创建 OAuth 2.0 客户端 ID:
    • Web 应用 → 得到 webClientIdxxxx.apps.googleusercontent.com),App 内使用此 ID
    • Android 应用 → 填写包名 + SHA-1(debug / release 各一份)
    • iOS 应用 → 填写 Bundle ID,配置 URL Scheme
  4. OAuth 同意屏幕设为 外部,测试阶段添加测试用户

获取 SHA-1:

keytool -list -v -keystore cert/app签名.jks -alias key0 -storepass YOUR_PASS

Android 平台配置

插件已在 AndroidManifest.xml 中声明网络权限,一般无需额外配置。确保 Cloud Console 中 Android OAuth 客户端 的包名、SHA-1 与当前安装 APK 签名一致。

iOS 平台配置

编辑插件内 uni_modules/wen-GoogleSignin/utssdk/app-ios/Info.plist,替换为实际值:

<key>GIDClientID</key>
<string>YOUR_IOS_CLIENT_ID.apps.googleusercontent.com</string>
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>com.googleusercontent.apps.YOUR_REVERSED_CLIENT_ID</string>
    </array>
  </dict>
</array>
  • YOUR_IOS_CLIENT_ID:iOS OAuth 客户端 ID
  • YOUR_REVERSED_CLIENT_ID:反向客户端 ID,如 123456-abc.apps.googleusercontent.comcom.googleusercontent.apps.123456-abc

如何使用

引入

import {
  configure,
  signInWithGoogleButton,
  signInSilently,
  signIn,
  signOut,
  getSignInState,
  getTokens,
  parseIdToken,
  checkPlayServices
} from '@/uni_modules/wen-GoogleSignin'

全局初始化

App.uvueonLaunch 中调用一次 configure

configure({
  webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
  preferCachedUser: true,
  fallbackToButtonOnNoCredential: true
})

configure 参数

参数 必填 默认 说明
webClientId Web OAuth Client ID
filterByAuthorizedAccounts false 标准/静默:仅使用设备已授权账户
autoSelectEnabled false 标准/静默:仅一个账户时自动选中
nonce "" 全局防重放随机串
preferCachedUser true 静默登录优先返回内存缓存
fallbackToButtonOnNoCredential true 无凭据时自动降级为按钮登录

Google 授权登录

Google 登录使用 OAuth 2.0,登录成功返回 idToken(JWT),须在后端验签。

首次登录(推荐:Google 按钮)

会弹出 Google 账号选择界面,适合首次登录:

signInWithGoogleButton({
  success: (res) => {
    console.log('✅ Google 登录成功')
    console.log('用户 ID:', res.user.id)
    console.log('邮箱:', res.user.email)
    console.log('已验证:', res.user.emailVerified)
    console.log('idToken:', res.user.idToken)

    // 将 idToken 发往后端验签
    sendIdTokenToServer(res.user.idToken)
  },
  fail: (err) => {
    console.error('❌ 登录失败:', err.errCode, err.errMsg)
    uni.showToast({ title: err.errMsg || '登录失败', icon: 'none' })
  },
  complete: () => {
    console.log('登录流程结束')
  }
})

再次打开(静默恢复)

不弹按钮,优先从缓存或 Google 静默获取凭据:

signInSilently({
  preferCachedUser: true,
  success: (res) => {
    if (res.fromCache) {
      console.log('来自缓存,未重新请求 Google')
    }
    console.log('用户:', res.user.email)
  },
  fail: (err) => {
    // 9010005 无凭据时可引导用户走按钮登录
    if (err.errCode === 9010005) {
      signInWithGoogleButton({ success: (r) => {} })
    }
  }
})

标准登录

底层 GetGoogleIdOption,无凭据时可自动降级按钮(默认开启):

signIn({
  nonce: generateNonce(),   // 可选,防重放
  success: (res) => {
    console.log('flow:', res.flow, 'stage:', res.stage)
  },
  fail: (err) => {}
})

统一入口

signInWithFlow('button', { success: (res) => {} })
signInWithFlow('silent', { preferCachedUser: true, success: (res) => {} })
signInWithFlow('default', { success: (res) => {} })

强制刷新 Token

refreshSignIn({
  success: (res) => {
    console.log('已刷新 idToken')
  }
})

登录成功返回值 GoogleSignInSuccess

字段 说明
user 用户信息,见下表
fromCache 是否来自内存缓存
flow 实际流程:default / silent / button
stage CM 阶段标识

user 字段:

字段 说明
id 用户唯一 ID,优先 JWT sub
email 邮箱
displayName 显示名
givenName / familyName 名 / 姓
photoUrl 头像 URL
idToken JWT,必须发往后端验签
emailVerified 邮箱是否已验证
hostedDomain Workspace 域名(hd
locale 语言区域
tokenPayload 完整 JWT 解析结果

登录参数 GoogleSignInOptions(各登录方法共用)

参数 必填 默认 说明
webClientId 取 configure 值 未 configure 时必填
nonce 取 configure 值 防重放,可用 generateNonce()
filterByAuthorizedAccounts 取 configure 值 signIn / signInSilently 有效
autoSelectEnabled 取 configure 值 signIn / signInSilently 有效
forceRefresh false signInSilently / refreshSignIn
preferCachedUser 取 configure 值 signInSilently
fallbackToButtonOnNoCredential 取 configure 值 无凭据降级按钮
success / fail / complete 回调

按钮登录(signInWithGoogleButton)不使用 filterByAuthorizedAccountsautoSelectEnabledpreferCachedUserforceRefreshfallbackToButtonOnNoCredential

行为说明

  • 登录成功必然返回 idToken
  • 建议使用 idToken 在后端验证用户身份
  • 按钮登录与标准/静默流程在 Credential Manager 中凭据不互通,插件通过缓存 + 自动降级处理

登录流程

signInSilently
  ├─ 有缓存且 preferCachedUser → 直接返回(fromCache=true)
  ├─ GetGoogleIdOption (filterAuthorized=true)
  │    └─ NoCredential → 放宽 filterAuthorized=false
  │         └─ NoCredential → 降级 signInWithGoogleButton
  └─ 成功 → 解析 idToken → 填充 user

signIn / signInWithGoogleButton
  └─ 同上(标准流程默认 filterAuthorized=false)

Google 退出登录

退出当前 Google 登录状态,清除设备端凭据。服务端 session 须自行失效。

signOut({
  success: () => {
    console.log('✅ 已登出')
    uni.showToast({ title: '退出成功', icon: 'success' })
  },
  fail: (err) => {
    console.error('❌ 登出失败:', err.errMsg)
  },
  complete: () => {}
})

// 同 signOut
revokeAccess({ success: () => {} })
disconnect({ success: () => {} })

状态查询与环境检测

// 聚合状态
const state = getSignInState()
console.log(state.configured, state.signedIn, state.user)

// 快捷查询
if (isSignedIn()) {
  const token = getIdToken()
  const user = getCurrentUser()
}

// Android:检测 Play 服务
checkPlayServices({
  success: () => console.log('Play 服务可用'),
  fail: (err) => console.error('Play 服务不可用', err.errCode)
})

const status = getPlayServicesStatus()
console.log(status.available, status.statusMessage)

Token 工具

// 解析 JWT(不验签,仅供展示)
const payload = parseIdToken(user.idToken)
console.log(payload.sub, payload.email, payload.exp)

// 检测是否过期(默认提前 60 秒判定)
if (isIdTokenExpired(user.idToken)) {
  refreshSignIn({ success: (res) => {} })
}

// 生成防重放 nonce
const nonce = generateNonce()

后端验签(必做)

  1. 使用 Google 公钥验证 JWT 签名
  2. 验证 aud === 你的 Web Client ID
  3. 验证 issaccounts.google.comhttps://accounts.google.com
  4. 验证 exp 未过期
  5. sub 作为用户唯一标识

错误处理

错误码

errCode 含义 常见原因
9010001 未 configure 未调用 configure 或未传 webClientId
9010002 无法获取 Activity 应用状态异常
9010003 Google Play 服务不可用 设备无 GMS 或版本过低(Android)
9010004 用户取消 用户主动取消登录
9010005 无可用凭据 首次登录或未授权,可降级按钮
9010006 凭据无效 / 无 idToken 凭据异常
9010007 清除凭据失败 登出失败
9010008 idToken 解析失败 Token 格式异常
9010009 未知错误 查看 errMsg / errType

错误处理示例

signInWithGoogleButton({
  success: (res) => {},
  fail: (err) => {
    switch (err.errCode) {
      case 9010003:
        uni.showModal({
          title: '提示',
          content: '请先安装或更新 Google Play 服务',
          showCancel: false
        })
        break
      case 9010004:
        console.log('用户取消登录')
        break
      case 9010005:
        console.log('无凭据,可引导首次登录')
        break
      default:
        console.error('登录失败:', err.errMsg)
    }
  }
})

常见问题

Q: 找不到插件方法?
A: 须使用自定义基座运行,标准基座不含原生插件。

Q: 按钮登录成功,标准/静默报 9010005?
A: 正常。Credential Manager 两套流程凭据不共享。保持 preferCachedUser + fallbackToButtonOnNoCredential 开启(默认已开)即可。

Q: Account reauth failed / 9010005?
A: Cloud Console Android OAuth 的 SHA-1、包名与当前 APK 签名不一致。

Q: Android 登录失败?
A: 检查 GMS 是否安装、SHA-1 / 包名、webClientId 是否为 Web Client ID

Q: iOS 登录无响应?
A: 检查 Info.plistGIDClientID、URL Scheme 是否与 Cloud Console iOS 客户端一致。

Q: 能否拿到 serverAuthCode?
A: 新 API 仅返回 idToken。请用 idToken 在后端建立 session。

Q: user.idemail 一样?
A: v1.1+ 已优先使用 JWT sub 作为 id


附:API 速查

模块方法

分类 方法
配置 configure
状态 isConfigured / getConfiguredWebClientId / isSignedIn / hasPreviousSignIn / getLastSignInFlow / getCurrentUser / getIdToken / getTokens / getSignInState
环境 checkPlayServices / getPlayServicesStatus / getPluginInfo
登录 signIn / signInSilently / signInWithGoogleButton / signInWithFlow / refreshSignIn
登出 signOut / revokeAccess / disconnect
工具 parseIdToken / isIdTokenExpired / generateNonce

本地打包

  1. HBuilderX 导出 app-android / app-ios 资源
  2. local-android.config.jsonplugins 加入 wen-GoogleSignin
  3. 执行本地打包脚本
  4. 产物可作为自定义基座调试

更新记录

  • 1.1.0 — 扩展 API、JWT 解析、状态查询、自动降级完善
  • 1.0.0 — 初始版本

隐私、权限声明

1. 本插件需要申请的系统权限列表:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件仅处理 Google 登录流程,不额外采集数据;登录数据由 Google 与开发者服务端处理。

3. 本插件是否包含广告:

无。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

请查看上方「权限要求」章节。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无。

暂无用户评论。