您可能是因为 Google Sign-In 应该是一个快速的集成,结果您却在凭据屏幕上苦苦挣扎,想知道为什么一个应用类型会给您一个客户秘钥,而另一个却不会。这种困惑是正常的,尤其是当您使用 Capacitor、Ionic、Electron 或混合的 Web 和本机堆栈时。
大多数指南都忽略了最关键的部分: Google 客户 ID 是平台特定的,并且非 Web 应用类型通常 不 会
获得客户秘钥。即使您创建了错误的凭据,只是为了强制秘钥进入流程,您也通常会得到一个更难调试的 OAuth 设置。
将您的应用程序连接到Google生态系统
许多团队在同一时间遇到这个问题。他们需要 使用Google登录, 或者他们想要获得像Drive或日历这样的服务的用户批准访问,而一个 API 键 suddenly 停止被允许。
,或他们想获得像Drive或日历这样的用户批准访问,并且一个__CAPGO_KEEP_0__密钥突然停止工作。 您的应用您的应用程序的身份,而不是仅仅被调用API。鉴定您的应用程序的凭证是 Google Client ID.
如果您正在使用跨平台的代码库,混淆会迅速加剧。您可能有一个Web前端,一个Android shell,一个iOS应用程序,甚至可能有一个Electron桌面构建。它们可能共享产品品牌和后端逻辑,但它们不应共享一个OAuth身份。
通常,实用的OAuth设置会涉及几个实现问题:
- 您应该创建哪种应用类型
- 您是否需要客户端密钥
- 哪些重定向URI或起源必须完全匹配
- 如何在不混淆凭据的情况下连接移动和Web流程
- 为什么浏览器中的流程会在原生包装器中失败
实用规则: 如果您的应用程序要求用户权限或登录,请先以OAuth客户端类型思考,而不是API键。
这种区分会节省早期时间。它还会防止在控制台显示更多字段的Web凭据上建立移动登录流程的常见错误。如果您正在在Capacitor应用程序中实施此功能,则请参阅 OAuth2在Capacitor应用程序中的指南 是应用侧流程的有用伴侣。
Google Client ID 是什么
A Google OAuth 2.0 客户 ID 是您的应用程序在 Google 认证系统中的公共标识符。 Google 将其描述为在请求 Google 认证端点时向 Google 认证端点请求访问令牌时应用程序的唯一用户名,并指出它与 API 密钥不同,因为它用于 OAuth 流程中验证应用程序身份以交换令牌,正如在 Google Cloud 的 OAuth 客户端文档中.

简单的心理模型
想象 客户 ID Google 发放的 是您的应用程序的公共用户名.
它告诉 Google,“这个请求来自这个注册的应用程序。”在登录、同意、令牌交换和任何流程中,这很重要,用户应用程序要求代表用户进行操作。客户 ID 旨在由应用程序和 Google 的身份验证服务器同时引用。
人们容易被困住的是,这个凭证位于两个概念旁边,它们是不可互换的。
客户 ID OAuth 中的应用程序标识
API 密钥 API 项目标识(某些不涉及委托用户授权的API 调用)
客户密钥 仅在安全可靠地保存密钥的流程和应用类型中使用的机密对应物。
很多破坏性集成都是因为有人把这些东西当作同一种东西来处理。它们不是。
客户 ID 在实践中的位置
如果您需要 使用 Google 登录 或 一键,前端使用的客户端 ID 值来启动身份验证握手。Google 的文档还指出,应用程序必须在专用 Cloud Console 项目中注册才能生成凭据,并且 Web 应用程序需要配置授权的 JavaScript 原始或重定向 URI,包括完整的方案和主机名。
因此,设置感觉比生成简单密钥更严格。Google 不仅仅是启用访问。它将身份验证请求绑定到已知应用程序身份。
对于构建混合应用的团队,安全的认知模型是这样的:
- 使用客户端 ID 来识别应用
- 使用同意屏幕来代表应用程序给用户
- 使用正确的应用类型来确定是否将密钥放在流程中
如果您想了解应用程序身份和委派访问如何结合在一起的更广泛的概述,请参阅 应用程序授权指南 创建和查看您的客户端 ID
appflow_plugins_or
console路径已经发生了足够大的变化,开发者经常认为自己在错误的地方。他们通常不是。 Google Auth 平台 > 客户端 APIs & Services > Credentials APIs & Services > 权限 Google的设置文档 一位正在使用笔记本电脑,显示Google Cloud控制台,用于创建OAuth 2.0客户端凭证的用户。.

打开Google Cloud控制台并选择或创建将拥有认证配置的项目。不要将认证分散到随机的项目中。它会使后期的审计和支持更加痛苦。
从那里,去到以下任何地方:
__CAPGO_KEEP_0__
- Google Auth 平台 > 客户端
- APIs & Services > 权限
如果您的团队看到不同的导航标签,这是正常的。Google已经将身份设置与API凭据表面分开。
创建凭据时不要限制自己
当您创建新的OAuth客户端时,最大决策是 应用类型Google 请求您选择特定的类型,如 Web, Web, Android, or iOS或
Desktop
- 已授权的 JavaScript 源
- 已授权的重定向 URI
这些值必须精确。对于 Web 凭据,Google 期望完整的方案和主机名,例如 https://www.example.com,而不是松散的域概念。
对于移动平台,形状不同。Android 注册需要包级别身份和所有权验证,而 iOS 使用其自己的平台标识符。如果您正在结合 Google 认证与另一个认证层 这个 Capacitor 社交登录设置与 Supabase 是一个有用的例子,展示了这些部分如何常常合并在一起。
如果您想比较 UI 并在点击时查看,请这个教程是一个不错的可视化参考:
在哪里找到它
创建后,客户端 ID 在项目的凭据列表中显示。同样,项目空间也是团队启用 API 和查看 OAuth 身份如何连接到-consent 屏幕的地方。注册应用程序的名称是用户在权限提示中看到的,这就是为什么准确命名应用程序很重要的原因。
Google 在管理这些凭据方面做得很好。您可以返回到控制台复制客户端 ID、查看设置,并在适用时管理与该凭据相关的客户端密钥。
同意屏幕不是装饰。它是信任边界的一部分。用户在那里看到应用程序名称,而不是内部项目的昵称。
平台特定客户端ID配置
破坏Google登录设置的最快方法是假设一个客户端ID可以覆盖所有平台。它不能。对于多平台应用,每个平台必须注册自己的独特OAuth 2.0客户端ID,并且Android设置特别需要SHA1指纹来验证所有权,正如在 平台设置参考.
为什么一个应用需要多个客户端ID
您的产品可能是用户看到的单个应用,但它是Google的多个OAuth客户端。
A Web应用,一个 Android构建,一个 iOS构建,和一个 桌面应用 它们不具备相同的安全性特性。它们无法以相同的方式证明身份,并且它们不存储凭证在可信的环境中。Google通过为每个平台提供自己的应用注册模型来处理这一点。
这一分离是良好的安全习惯。如果一个平台的凭证设置被破坏或配置不当,其他平台不会自动暴露。
以下是实用的分离方案:
- Web 使用Web客户端ID和严格的源和重定向URI匹配。
- Android 使用与包标识和SHA1指纹相关联的Android客户端ID。
- iOS 使用与应用程序包标识相关联的iOS客户端ID。
- 桌面或Electron 通常使用安装或桌面样式的OAuth模式,而不是秘密背后的浏览器流程。
Google Client ID 类型比较
| 应用类型 | 主要标识符 | 是否提供客户端密钥? | 关键用例 |
|---|---|---|---|
| Web | 授权 JavaScript 源和重定向 URI | 通常是的 | 浏览器应用和后端辅助 OAuth |
| Android | 包标识符加 SHA1 指纹 | 通常不是 | 原生 Android 登录 |
| iOS | 应用程序包标识 | 通常没有 | 原生 iPhone 和 iPad 登录 |
| 桌面 | 已安装应用程序标识 | 通常没有 | 包括 Electron 风格的本机流程的桌面应用程序 |
移动和桌面开发人员经常期望每个 OAuth 客户端都带有
这就是许多教程所犯的错误。
OAuth 客户端的客户端密钥 客户端 ID 和一个 客户端密钥. 然后他们创建一个 Web 应用 凭证,因为这是在控制台中看到秘密的唯一方法。 流程看起来更完整,所以他们继续。 后来,身份验证在令人困惑的方式中出现问题。
根据 这个移动凭证不匹配的说明, 非 Web 应用类型,如 Android、 iOS 和安装的应用程序经常接收一个客户端 ID 但没有客户端密钥的故意,因为 Google 不希望在客户端软件中嵌入一个保密的密钥,用户可以从中提取它。
这个设计选择是正确的。 移动应用程序或 Electron 包不是安全的秘密存储器。
什么有效: 为公共客户端设计的本机或客户端 OAuth 流程
什么不应该做: 仅为了强制将秘钥塞入实现中,创建一个针对移动应用的 Web 凭证。
对于 Capacitor 团队来说,这通常会出现在以下两种糟糕的模式中:
- 应用程序使用一个 web 客户端 启动浏览器流程,然后尝试像一个保密服务器一样行为。
- 应用程序从捆绑的 __CAPGO_KEEP_0__ 中发送一个 客户端秘钥 从打包的 code 中,实际上这是违反了保密的目的。
更好的方法是将移动和桌面应用程序视为 公共客户端 。在现代 OAuth 中,这通常意味着使用不依赖于客户端内置秘钥的流程。如果您的后端参与其中,请将保密操作保留在后端,仅将本机应用程序限制为公共客户端应该做的事情。
另一个细微的点对于 Firebase-backed Android 登录很重要。在这种设置中, web 应用类型的客户 ID 被用作后端服务器的 OAuth 客户 ID,而 Android 应用则保留自己的平台特定身份。这种分离会使团队感到困惑,因为他们会看到同一个项目中同时出现 web 凭证和移动凭证,认为其中一个会取代另一个。然而,它们并不互相取代。它们各自扮演不同的角色。
如果你记住一个规则,那么这个规则就是: 选择匹配 code 运行的客户端类型,而不是你希望拥有的凭证形状.
保护您的 Google API 凭证
大多数 OAuth 事件并不是由复杂的攻击引起的。团队泄露凭证、过度扩大重定向设置或将机密放入不应放入的地方都是常见的错误。
Google 的 OAuth 指南强调,客户 ID 和机密应该被视为私有数据,针对 web 应用,客户 ID 将被强制与预注册的重定向 URI 进行绑定。如果重定向 URI 不严格匹配,Google 将拒绝请求。这一原发绑定是保护令牌劫持的关键部分,正如描述在 OAuth.com 的客户注册指南.

立即锁定什么
如果你只做几件事正确,那么这些就是你需要做的:
- 绝不将客户端密钥在应用程序中 code 发送。 Web 包、移动二进制文件和 Electron 包都可以让用户进行检查。
- 注册准确的重定向 URI。 不够好并不能满足要求。Google 验证了严格匹配的 Web 流程。
- 保持源头紧密。 不要仅仅为了方便而授权广泛的域名。
- 分离平台凭证。 不要让便利性将 Android、iOS 和 Web 凭证合并为一个凭证。
有一点操作细节容易被忽略。Google 允许团队为现有的客户 ID 生成新密钥并禁用旧密钥。这在密钥被泄露或您正在优化部署过程时很重要。
安全团队实际上做什么
那些不惹麻烦的团队对 OAuth 凭证的处理与其他生产密钥一样。
他们将 Web 客户端密钥保留在后端,通过环境管理注入它们,并审计谁有控制台访问权限。如果您正在清理发布管道,这个指南 CI/CD管道中的机密管理 同样适用于您的身份验证设置。
它们还会审查元数据,而不仅仅是密钥。 OAuth-consent 屏幕与用户看到的客户端身份相关联。如果应用程序名称模糊或误导性,用户更有可能不信任提示或批准错误应用程序。
安全性不仅仅是隐藏一个机密。它还要确保每次都正确的应用程序身份、重定向目标和批准屏幕的对齐。
解决常见的客户端 ID 错误
大多数 Google OAuth 失败都是由于设置错误引起的。错误消息可能不友好,但一旦您知道哪里看,问题通常是相当直接的。
解决大多数失败的修复
redirect_uri_mismatch
您的应用程序发送的重定向 URI 与注册的 Web 客户端不完全匹配。检查方案、主机、路径和任何尾随差异。对于 Web OAuth,精确匹配是安全模型的一部分。
invalid_client
这通常意味着应用程序发送了错误的客户端 ID、错误的密钥或在不同平台之间混合了凭据。常见的例子是 Android 或 iOS 流程意外使用了 Web 凭据的错误位置。
invalid_request
这是一个广泛的问题,但在跨平台应用中,它通常指向不正确的身份验证参数或不适合客户端类型的流程。检查应用程序是否尝试在不应该的地方包含密钥,还是选择的 OAuth 流程期望的客户端类型不同。
Google Sign-In 在 Web 上工作,但在移动设备上失败
首先需要检查的是客户端类型。移动开发人员最常见的错误来源是创建一个网页应用客户端 ID,仅仅为了获取客户端密钥,而实际上应该使用 Android 或 iOS 类型,这些类型通常会省略密钥,正如在 客户端密钥不匹配的分解中中所解释的那样。如果您的实现包含在登录后进行令牌生命周期工作的步骤,那么取消授权指南也是很有用的。
Android 登录失败后凭据创建
检查 Android 客户端附加的 SHA1 FingerPrint。如果签名身份与 Google 期望的不符,应用就无法正确证明所有权。
-consent 屏幕看起来不正确
验证在控制台中设置的 OAuth 配置中的应用名称和品牌。用户授权的是他们在那里看到的内容,因此错误的元数据会导致信任问题和支持噪音。
调试的实践顺序很简单:首先检查客户端类型,然后检查重定向设置,接着检查平台标识符,最后检查是否在流程中需要密钥 如果您的团队部署 Astro 或 Electron 应用,授权错误很少会孤立。它们通常会在发布压力、回滚需求和环境特定修复中浮现。.
Capacitor Capgo code