更新记录
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,获取
sub、email_verified、hd等字段 - 提供登录状态查询、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 必须发往后端验签
环境配置
前置条件
- 在 Google Cloud Console 创建项目
- 启用 Google Sign-In / Identity 相关 API
- 创建 OAuth 2.0 客户端 ID:
- Web 应用 → 得到
webClientId(xxxx.apps.googleusercontent.com),App 内使用此 ID - Android 应用 → 填写包名 + SHA-1(debug / release 各一份)
- iOS 应用 → 填写 Bundle ID,配置 URL Scheme
- Web 应用 → 得到
- 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 客户端 IDYOUR_REVERSED_CLIENT_ID:反向客户端 ID,如123456-abc.apps.googleusercontent.com→com.googleusercontent.apps.123456-abc
如何使用
引入
import {
configure,
signInWithGoogleButton,
signInSilently,
signIn,
signOut,
getSignInState,
getTokens,
parseIdToken,
checkPlayServices
} from '@/uni_modules/wen-GoogleSignin'
全局初始化
在 App.uvue 的 onLaunch 中调用一次 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)不使用filterByAuthorizedAccounts、autoSelectEnabled、preferCachedUser、forceRefresh、fallbackToButtonOnNoCredential。
行为说明
- 登录成功必然返回
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()
后端验签(必做)
- 使用 Google 公钥验证 JWT 签名
- 验证
aud=== 你的 Web Client ID - 验证
iss为accounts.google.com或https://accounts.google.com - 验证
exp未过期 - 以
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.plist 中 GIDClientID、URL Scheme 是否与 Cloud Console iOS 客户端一致。
Q: 能否拿到 serverAuthCode?
A: 新 API 仅返回 idToken。请用 idToken 在后端建立 session。
Q: user.id 和 email 一样?
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 |
本地打包
- HBuilderX 导出
app-android/app-ios资源 local-android.config.json→plugins加入wen-GoogleSignin- 执行本地打包脚本
- 产物可作为自定义基座调试
更新记录
- 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. 本插件是否包含广告:
无。

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 4
赞赏 0
下载 12277918
赞赏 1922
赞赏
京公网安备:11010802035340号