你可能已经遇到过这个问题。 应用登录正常,用户可以使用Google、Microsoft或电子邮件登录,并且API接受令牌。 然后,核心问题出现了。 这个用户是否可以从另一个帐户中查看发票? 桌面应用是否应该在本地缓存访问令牌? 如何在Capacitor构建中处理同意而不泄露状态跨越浏览器和本机层?
这就是应用授权停止成为一个复选框并开始影响产品信任、事件响应和应用商店审查结果的地方。 在跨平台应用中,尤其是Capacitor和Electron,困难的部分不是理解授权的概念。 而是在理解授权的概念后,如何在浏览器假设不再适用的地方、安全存储在不同平台上表现不同、客户端的捷径会在服务器端造成风险的地方实施它。
目录
应用授权的真正含义
用户安装您的应用程序,点击“继续使用 Google”,成功签入,然后出现一个同意屏幕,询问应用程序是否可以读取联系人或日历数据。这个时刻包含了两方面的访问故事。签入确认了身份。同意屏幕定义了应用程序在身份已知后可以做什么。
即使是这一区别也会让团队陷入困境。 身份验证 证明用户身份 Authorization 决定了用户、会话或应用程序可以访问什么。一个 ID 可以进入建筑物,而一个密钥则决定哪些门可以打开。
在应用程序工作中,这个区别很重要,因为团队经常在登录流程中进行安全设置,然后在其后设计不足。他们过度信任令牌,跳过服务器端权限检查,或者让客户端驱动访问规则,这些规则应该在政策中存储。因此,“用户已登录”会悄悄地变成“用户可以访问太多内容”。
Authorization 是信任变为具体的时刻。用户不仅关心您的应用程序知道他们是谁。他们关心它只触摸他们批准的内容。
需要记住的三个角色是:
- 用户 签入并可能授予同意。
- 应用程序 代表用户请求访问。
- 资源所有者或API 保护数据并执行决策。
在实践中,应用程序授权也与更强大的访问控制(如 MFA)重叠。截至 2023 年 1 月, 全球约有 66% 的用户正在使用 MFA, 和 83% 的超过 1,000 名调查的中小企业 IT 专业人员要求 MFA 访问公司资源的所有资源 根据 JumpCloud 的 MFA统计数据总结。 这并不会取代授权,但它确实提高了谁可以要求访问的基线。
如果您的团队正在处理角色、范围和委托访问,这个 应用程序访问管理模式 的概述是一个有用的伴侣,讨论这里的实现选择。
授权的基本构建块
授权会变得更容易一旦你停止将其视为令牌内部的神奇东西。一个更好的思维模型是酒店。
酒店卡是酒店的好思维模型
A客人走到前台,展示身份证。酒店验证身份,创建入住记录,并发放一张卡片。该卡片并不能证明客人身份每次门被打开时。它携带着在有限时间内访问特定场所的许可。
您的应用程序与此类似。

关键点在于卡片并不是策略。它反映了策略。门仍然需要一个系统来检查卡片是否应该打开特定的锁。 在软件中,这就是您的API网关、后端中间件、策略引擎或服务级别授权层。
在实际系统中,重要的术语
主体
请求访问的主体。通常是用户,但也可以是设备、后台作业或服务账户。
资源
被保护的东西。一个项目、发票、管理员路由、文件、API端点或数据库中的一个记录。
范围
被请求的动作集合。读取个人资料。上传文件。管理账单。范围应该狭窄且易于理解。
同意
The user’s approval for a requested level of access. Good consent screens make the request legible. Bad ones ask for everything.
访问令牌
The credential the client presents to a resource server after authorization succeeds. It should be treated as sensitive data.
很多实现错误来自于压缩所有这些信息到一个单一假设:‘用户有令牌,允许他们进入。’但这在生产环境中并不成立。令牌可能是有效的,但仍然不适合当前的操作、租户、环境或资源。
对于移动和桌面团队来说,令牌处理需要特别关注,因为存储是授权系统的一部分,无论你是否喜欢。 如果客户端存储访问艺术品不当,您的策略设计将无法在后期保护您。 在您交付之前,值得一阅的关于 移动开发人员的安全令牌存储指南 一个可靠的规则很简单。 在您的头脑中和您的__CAPGO_KEEP_0__中,保持身份验证、同意、令牌颁发和服务器端强制执行分开。 合并它们的团队通常会在错误的层面上调试权限错误。
A durable rule is simple. Keep authentication, consent, token issuance, and server-side enforcement separate in your head and in your code. Teams that merge them usually end up debugging permission bugs in the wrong layer.
当团队说‘我们正在使用 OAuth’时,他们通常同时指的是几种不同的东西。 这是混淆的部分。 协议和授权模型解决不同的问题。
协议处理对话
OAuth 2.0
__CAPGO_KEEP_0__ 主要是关于委托授权的。它定义了应用程序如何请求和接收授权以在不直接处理用户密码的情况下代表用户采取行动。
OpenID Connect或 OIDC, 在 OAuth 2.0 之上添加身份信息。从实际角度来说,OAuth 回答“这个应用程序可以做什么”,而 OIDC 帮助回答“谁登录了”。
这种区别在 Capacitor 和 Electron 应用程序中很重要,因为许多 bug 都源于使用 ID 令牌而不是访问令牌,或者假设登录成功意味着 API 应该授权所有下游操作。它不应该。
如果您将其集成到混合应用程序中,则需要逐步 OAuth2 implementation guide for Capacitor apps 是预防许多可避免的流程错误的资源。
模型处理决策逻辑
在您的内部系统中,您仍然需要为决定是否授予访问权限而制定规则。这就是 RBAC 和 ABAC 可适入开。
角色权限控制(RBAC) 将权限映射到角色,如管理员、编辑、支持人员或查看者。它是常见的,因为它易于理解、可审计且相对稳定。根据 BrightSec关于安全身份验证和授权的讨论, RBAC是行业标准的机制,用于强制实施细粒度权限, ,并且在那里提到的证据表明,使用层次结构角色和定期权限审计的RBAC.
在企业环境中可以减少安全事件的发生率达40% 基于属性的访问控制(ABAC)
使用属性而不是仅仅角色来做出决定。可以包括部门、设备状态、记录所有权、账户等级、地理位置、请求时间或会话是否通过MFA。ABAC更具表达性,但也更容易变得不透明,如果不好好记录政策 实践建议:
在您的产品权限稳定且易于阅读时,首先使用RBAC。添加ABAC在上下文实际上会改变决策时
| 标准 | 基于角色的访问控制 (RBAC) | 基于属性的访问控制 (ABAC) |
|---|---|---|
| 核心思想 | 通过角色授予访问权限 | 通过评估属性授予访问权限 |
| 最佳选择 | 内部工具、仪表板、管理面板 | 多租户应用、受管工作流、基于上下文的访问 |
| 推理的便利性 | 更易于团队和审计人员理解 | 更灵活,但更难调试 |
| 变更管理 | 添加或修改角色 | 调整策略和属性规则 |
| 常见故障模式 | 角色过载 | 策略过载和隐蔽边缘案例 |
| 示例 | “支持人员可以查看票据” | “支持人员可以在活动shift期间查看其区域内的票据” |
选择最先进的模型并不是最好的选择。更好的选择是您的团队可以一致地执行的选择。在大多数产品代码库中,这意味着使用RBAC进行广泛访问边界,并针对如拥有权、租户或设备状态等异常情况使用目标属性。
OAuth 2.0 流程解剖
很多OAuth说明过于抽象,时间太长了。在一个真正的应用程序中,顺序很重要,尤其是对于无法安全地保留客户机密的公共客户端,如Capacitor和Electron应用程序。
当用户点击登录时会发生什么
用户打开您的Capacitor应用并点击“使用GitHub登录”。应用程序创建一个PKCEcode验证器和一个派生的code挑战,然后将用户转到授权服务器,在系统浏览器或安全浏览器标签中。应用程序还包括状态,以便验证响应属于它启动的请求。

在授权服务器上,用户如果需要则登录并批准所请求的访问权限。然后服务器重定向回去带有授权code,而不是带有长期凭证可以直接使用的凭证。您的应用程序通过配置的重定向URI接收了该code。
应用程序然后将code兑换成令牌。PKCE在这个过程中至关重要。应用程序发送原始code验证器以及授权code。服务器将其与之前的code挑战进行比较。如果它们匹配,则令牌交换成功。如果有人拦截了code但没有验证器,则交换失败。
这就是为什么PKCE对于原生和混合客户端至关重要。这些应用程序是公共客户端。您应该假设攻击者可以检查捆绑包、逆向工程code路径或篡改本地状态。PKCE减少了重定向流程中最常见的风险之一。
如果您想在code中实现序列之前进行视觉刷新,以下是一个简短的指南。
跨平台应用通常会在__CAPGO_KEEP_0__中断
The protocol is straightforward. The implementation often isn’t.
Capacitor apps通常在以下地方会失败:
- 使用嵌入式网页视图进行登录 而不是系统浏览器。这可能会破坏预期的安全边界并导致cookie行为不一致。
- 在app从浏览器恢复到原生壳时丢失重定向状态。 因为项目最初是web应用,团队从未重新审视移动设备的存储。
- Electron应用有不同的问题。团队有时会让渲染进程处理太多的认证逻辑,通过IPC暴露令牌而没有严格的边界,或者将桌面应用视为可信的环境。它不是。一个打包的桌面应用仍然需要一个敌对客户端的思维方式。 刷新行为也需要有意识的设计。访问令牌应该过期,会话应该清洁地恢复,并且刷新逻辑不应在多个并发请求之间创建竞争条件。这
安全令牌刷新流程指南
是构建这一部分而不陷入重试循环或过期会话的混乱的坚实参考。 __CAPGO_KEEP_0__ __CAPGO_KEEP_0__
保持 OAuth 握手的习惯比大多数人有用。将 OAuth 握手隔离在一个小的认证模块中,明确输入和输出。不要在组件、钩子和随机网络工具中散布重定向处理、令牌解析和刷新逻辑。
安全威胁和必备最佳实践
授权错误很少在code审查中看起来很戏剧化。它们看起来像便利的功能。这里有一个广泛的范围,那里有一个缓存的令牌,UI 已经隐藏了按钮。然后应用程序发布,这些捷径变成了攻击面。
不断出现的失败
移动生态系统提供一个有用的警告信号。根据 DeepStrike 的移动安全统计数据, 95% 的测试移动应用程序至少在一个 OWASP MASVS 控制中失败了,相关于身份验证和授权, 和 85% 的分析移动应用程序包含安全漏洞。您不需要接受安全营销的每个框架来认真对待核心信号。授权错误是常见的。

熟悉的模式:
- 泄露的令牌 来自不安全的存储、日志、崩溃报告或渲染器可访问的状态。
- 过度权限 因为要求所有内容比逐渐演进的同意更容易。
- 客户端强制 应用程序隐藏未经授权的操作,但API仍然接受它们。
- 重放和重定向攻击 状态、PKCE 或重定向 URI 验证不当时发生。
- 权限漂移 团队添加角色和例外时不定期进行审查后发生的。
如果您的后端在每个受保护的操作中都没有验证授权,那么您就没有应用程序授权。您有 UI 提示。
一个实用的检查清单,仍然有效
以最小特权原则作为默认设置,而不是稍后清理工作。 在实际项目中,这意味着缩小每个令牌的权限、缩小每个令牌的存储位置以及缩小每个凭据的有效期。
- 请求狭窄的权限: 只为当前用户正在使用的功能请求所需的权限。如果应用程序可以推迟同意,请这样做。
- 在服务器上强制执行: 将客户端视为不受信任的。按钮、路由和隐藏屏幕不是安全边界。
- 使用平台安全存储: 在移动设备上,使用native keychain或keystore访问通过插件而不是普通本地存储。 在桌面上,将敏感信息保持在易于渲染的范围之外。
- 验证状态和重定向处理: 认证响应必须与应用程序发起的请求匹配。
- 积极过期并谨慎刷新: 短暂的访问令牌限制了它们泄露的损害。 刷新逻辑应该旋转干净并关闭失败。
- 在需要时撤销: 会话终止和事件响应应包括invalidate令牌和强制重新认证的能力。
- 验证输入并保护传输: HTTPS、适当的证书固定以及输入验证都很重要,因为授权可以通过邻近的弱点绕过。
对于通过商店发布应用的团队,认证设计也与API暴露和合规审查相交叉。这个API应用商店合规的安全标准概要适合与您的授权清单一起使用。 API security standards for app store compliance __CAPGO_KEEP_0__和Electron的实现模式
跨平台应用授权变得更容易,当您停止假设应用只是一个浏览器加上额外的打包时。__CAPGO_KEEP_0__和Electron都需要遵循本机存储、进程边界和重定向处理的模式。
专注的年轻开发人员在办公室环境中工作着,Capacitor在显示器上。
适用于Capacitor的模式

Capacitor patterns that work
For Capacitor, use a plugin or auth library that supports system-browser OAuth with PKCE and a proper deep-link or app-link callback. Libraries like capacitor-oauth2 可以移除大量胶水 code, 但只有当您仍然保持令牌存储和刷新行为明确时。
实用结构如下:
- 认证协调器: 开始登录,跟踪状态,处理回调。
- 令牌服务: 通过本机安全存储而不是浏览器存储存储令牌。
- API 客户端: 附加访问令牌,刷新一次,然后在不可恢复的失败时强制注销。
- 政策敏感的后端: 将令牌声明映射到服务器端授权检查。
您还希望session工具与混合应用程序生命周期相匹配。如果您正在评估该层的选项, Capacitor 插件用于安全会话管理 是一个比较方法的好地方。
在伪代码中,一个最小的token刷新形状看起来像这样:
async function authorizedFetch(request) {
let token = await tokenStore.getAccessToken()
let response = await api(request, token)
if (response.status !== 401) return response
const refreshed = await auth.refresh()
if (!refreshed) {
await auth.signOut()
throw new Error('Session expired')
}
token = await tokenStore.getAccessToken()
return api(request, token)
}
重要的不是语法。重要的是保持刷新集中化,以便每个屏幕不需要自己发明会话行为。
需要额外小心的Electron模式
Electron需要更严格的边界。尽可能在主进程中保留token交换和安全存储。通过暴露窄的IPC方法来向渲染器暴露,而不是将渲染器直接暴露给原始token并希望它表现良好。
桌面应用程序感觉更可控。将这种感觉视为风险,而不是保证。
避免这些捷径:
- 不要在渲染器可访问的本地存储中存储token 如果可以避免的话。
- 不要让每个窗口共享广泛的认证上下文 不检查窗口目的和会话生命周期。
- 不要过于信任预加载脚本 作为进程隔离和明确的API边界的替代方案。
运营可见性也很重要。根据 Splunk对应用安全需求概述,应用授权应与持续活动监控和日志记录集成,引用中提到的benchmark数据表明,组织可以通过预先记录和监控授权事件, 在15分钟内检测出95%的未经授权的访问尝试。在实践中,这意味着记录被拒绝的操作、令牌刷新失败、角色变化、-consent revocation和异常资源访问模式。
如果您的发布过程包括混合应用更新,那么在这个生态系统中一个可行的选项是 Capgo,它为Capacitor和Electron应用提供了签名的实时更新。这个选项并没有为您实现授权,但它确实影响了您可以快速发布修复时的速度,尤其是当需要紧急修复授权逻辑、重定向处理或会话code时。
您的安全应用授权之路
良好的应用授权不是一个决定。它是一个链条,所有的决定都需要相互支持。您正确地验证用户,请求所需的访问权限,通过安全流程如OAuth 2.0 with PKCE交换令牌,存储秘密在合适的位置,并在服务器端每次强制执行权限。
最重要的部分是 Electron 和 Capacitor 团队需要遵守的纪律。浏览器时代的快捷方式在接触本地存储、深度链接、桌面进程边界或应用审查要求时都无法幸免。通常不太麻烦的团队并没有做什么特别的事情。他们只是在作用域、会话处理、服务器端检查和审计性方面保持一致。
如果您的当前认证设置感到混乱,那是正常的。从一个边界开始逐步加紧。修复流程。修复存储。将访问规则从 UI 中移除。添加日志以告知您何时有人要求他们不应该有的东西。
这就是如何使应用授权变得可管理的方法。理论上没有变得更简单。 code 中更安全。
Capgo 帮助团队在 Electron 和 Capacitor 应用中修复问题而不必等待商店审查,这在您需要快速修复认证流程、令牌处理或会话错误时尤其重要。如果您的团队想要更紧密地控制跨平台发布、目标发布和回滚支持, Capgo 值得与您的应用授权堆栈一起评估。