你可能已经遇到过这个问题。应用程序登录正常,用户可以使用 Google、Microsoft 或电子邮件登录,并且 API 接受令牌。然后,核心问题开始出现。这个用户是否可以从另一个帐户查看发票?桌面应用程序是否应该在本地缓存访问令牌?如何在 Capacitor 构建中处理同意,而不泄露状态跨越 webview 和本机层?
这就是应用程序授权停止成为一个复选框并开始影响产品信任、事件响应和应用商店评审结果的地方。在跨平台应用中,尤其是 Capacitor 和 Electron,困难之处不在于理解授权的概念。它在于在浏览器假设不再适用、安全存储在各个平台上表现不同、客户端快捷方式在服务器端造成风险的位置中实施它。
目录
应用授权的真正含义
用户安装了您的应用,点击“继续使用 Google”,成功登录,然后看到一个询问是否允许应用读取联系人或日历数据的-consent 屏幕。这个瞬间包含了身份确认和授权的两方面。登录确认了身份,consent 屏幕定义了应用在身份已知后可以做什么。
仍然会让团队感到困惑。 认证 证明用户的身份。 授权 决定用户、会话或应用程序可以访问什么。一个 ID 可以让你进入大楼。一个钥匙决定哪些门可以打开。
In app work, that difference matters because teams often secure the login flow and then under-design everything after it. They trust a token too broadly, skip server-side permission checks, or let the client drive access rules that should live in policy. That’s how “user is logged in” subtly transforms into “user can access too much.”
授权是信任变得具体的地方。用户不仅关心你的应用程序知道他们的身份。他们关心它只触摸他们批准的东西。
有三个角色需要注意:
- 用户 签入的用户可能会同意授权。
- 用户 who signs in and may grant consent. 他们可能会同意授权。
- 资源所有者或API 保护数据并执行决策。
实践中,应用授权也与更强大的访问控制,如 MFA 重叠。截至 2023 年 1 月, 全球约有 66% 的用户使用 MFA,并且 超过 1,000 名调查的中小企业 IT 专业人员中,83% 的人要求 MFA 对所有公司资源的访问 根据 JumpCloud 的 MFA 统计总结。这并没有取代授权,但它确实提高了首先要求访问的用户的基线。
如果您的团队正在处理角色、范围和委托访问,这个应用访问管理模式的概述 是这里讨论的实现选择的有用补充。 应用授权
认证的基础
认证变得更容易一旦你不再把它当作一个魔法令牌。一个更好的认知模型是酒店。
酒店卡是好的认知模型
客人走到前台,展示身份证。酒店验证身份,创建入住记录,并发放酒店卡。这个卡片并不是证明客人身份的证据。它携带着在特定时间段内访问特定地方的许可权。
你的应用程序也一样。

重要的是,卡片并不是策略。它反映了策略。门仍然需要一个系统来检查卡片是否应该打开特定的锁。软件中,这就是你的API网关、后端中间件、策略引擎或服务级别认证层。
在实际系统中,重要的术语
主体
请求访问的主体。通常是用户,但也可以是设备、后台作业或服务账户。
资源
被保护的东西。一个项目、发票、管理员路由、文件、API端点或数据库中的一个记录。
范围
请求的动作集合。读取用户资料。上传文件。管理账单。权限范围应尽可能狭窄和易于理解。
同意
用户同意某一权限级别的请求。良好的同意界面应使请求清晰易懂。糟糕的同意界面会要求用户同意所有权限。
访问令牌
客户端在授权成功后向资源服务器提交的凭证。应将其视为敏感数据。
许多实现错误源于将所有这些功能压缩到一个假设中:‘用户有令牌,允许他们进入。’但这在生产环境中并不成立。令牌可能是有效的,但仍然不适用于当前的动作、租户、环境或资源。
对于移动和桌面团队来说,令牌处理需要特别关注,因为存储是授权系统的一部分,无论你是否喜欢。客户端如果不小心存储访问艺术品,政策设计就无法在后期保护你。这篇关于 移动开发人员安全令牌存储指南 值得在发布之前阅读。
一个可靠的规则很简单。将认证、同意、令牌颁发和服务器端强制执行分开在你的头脑中和在你的code中。将它们合并的团队通常会在错误的层面上调试权限错误。
常见的授权模型和协议
当团队说“我们正在使用 OAuth”,他们经常同时指代多个不同的事情。这就是混淆的原因。协议和授权模型解决不同的问题。
协议处理对话
OAuth 2.0 主要是关于委托授权的。它定义了应用程序如何请求和接收权限以在不直接处理用户密码的情况下代表用户行动。
OpenID Connect,或 OIDC,位于 OAuth 2.0 之上并添加身份信息。在实际情况下,OAuth 回答“这个应用程序可以做什么”,而 OIDC 帮助回答“谁登录了”。
在 Capacitor 和 Electron 应用程序中,这个差异很重要,因为许多 bug 都源于使用 ID 令牌而不是访问令牌,或者假设登录成功意味着 API 应该授予所有下游操作。它不应该。
如果您正在将其集成到混合应用程序中,一个步骤-by 步的 OAuth2 implementation guide for Capacitor apps 是预防可避免流程错误的资源。
模型处理决策逻辑
在您的内部系统中,您仍然需要规则来决定是否应授予访问权限。这就是 RBAC 和 ABAC 来到。
基于角色的访问控制(RBAC) 将权限映射到角色,如管理员、编辑、支持人员或查看者。它是常见的,因为它是可理解的、可审计的和相对稳定的。根据 BrightSec关于安全认证和授权的讨论, RBAC是行业标准的机制,用于强制实施细粒度权限,据该讨论中提到的证据表明,使用层次结构角色和定期权限审计的RBAC 在企业环境中可以降低安全事件的发生率达40%.
基于属性的访问控制(ABAC) 使用属性而不是仅仅角色来做出决定。可以包括部门、设备状态、记录所有权、账户等级、地理位置、请求时间或会话是否通过MFA。ABAC更具表达性,但如果不对政策进行良好的文档化,则更容易变得不透明。
实用规则: 在产品权限稳定且易读时,首先使用 RBAC。 在实际上下文改变决策时,添加 ABAC。
RBAC 与 ABAC 比较
| 标准 | 基于角色的访问控制 (RBAC) | 基于属性的访问控制 (ABAC) |
|---|---|---|
| 核心思想 | 通过角色授予访问权限 | 通过评估属性授予访问权限 |
| 最佳匹配 | 内部工具、仪表板、管理面板 | 多租户应用、受管工作流、上下文敏感访问 |
| 简化认证 | 更易于团队和审计人员理解 | 更灵活但更难调试 |
| 变更管理 | 添加或修改角色 | 调整策略和属性规则 |
| 常见故障模式 | 角色过载 | 策略过载和隐蔽边缘案例 |
| 示例 | “支持人员可以查看票据” | “支持人员可以在活动shift期间查看其区域内的账户票据” |
选择最先进的模型并不是什么奖项。更好的选择是你团队能一致执行的方案。在大多数产品代码库中,这意味着使用RBAC来定义广泛的访问边界,并针对特定场景,如拥有权、租户或设备状态等,使用目标属性来进行例外处理。
OAuth 2.0 流程的解剖学
太长时间的 OAuth 描述往往过于抽象。在一个真实的应用中,顺序很重要,尤其是对于无法安全地保留客户端秘钥的公共客户端,如 Capacitor 和 Electron 应用。
用户点击登录时发生什么
A user opens your Capacitor app and taps “Login with GitHub.” The app creates a PKCE code verifier and a derived code challenge, then sends the user to the authorization server in a system browser or secure browser tab. The app also includes state so it can verify the response belongs to the request it initiated.

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

这些模式很熟悉:
- 泄露的令牌 从不安全的存储、日志、崩溃报告或可渲染的状态中。
- 过度的授权范围 因为要求所有内容比逐渐演进的同意更容易。
- 客户端的强制执行 应用程序隐藏未经授权的操作,但API仍然接受它们。
- 重放和重定向攻击 当状态、PKCE或重定向URI验证不当时。
- 权限漂移 在团队添加角色和例外时没有定期审查。
如果您的后端在每个受保护的操作中不验证授权,那么您没有应用授权。您有UI提示。
一个实用的检查清单
以最小权限原则作为默认值,而不是稍后清理工作。 在实际项目中,这意味着缩小每个令牌可以做的事情、缩小每个令牌存活的位置以及缩小每个凭据的有效期。
- 请求狭窄的权限: 只为用户当前使用的功能请求所需的权限。如果应用可以延迟-consent,请这样做。
- context 在服务器上强制执行:
- 将客户端视为不信任的。按钮、路由和隐藏屏幕不是安全边界。 使用平台安全存储:
- 验证状态和重定向处理: 您的应用程序发起的请求必须与响应匹配。
- 过期激进,刷新谨慎: 短期访问令牌限制了泄露的损害。 刷新逻辑应清晰旋转并关闭失败。
- 需要时撤销: 会话终止和应急响应应包括invalidate令牌和强制重新验证的能力。
- 验证输入并保护传输: HTTPS、适当的证书固定以及输入验证都很重要,因为授权可以通过邻近的弱点绕过。
对于通过商店发布应用的团队,认证设计也与API暴露和合规审查相交。 这个API安全标准的摘要适合与您的授权清单一起使用。 API 应用商店安全标准 __CAPGO_KEEP_0__和Electron的实现模式
__CAPGO_KEEP_0__安全标准
Capacitor
当你停止假装你的应用程序只是一个浏览器加上额外的打包时,跨平台应用程序授权变得更加容易。 Capacitor 和 Electron 都需要尊严存储、进程边界和重定向处理的模式。

Capacitor 模式
对于 Capacitor,使用支持系统浏览器 OAuth(PKCE)和深度链接或应用链接回调的插件或认证库。类似于 capacitor-oauth2 可以减少大量粘合剂 code,但只有当你仍然保持令牌存储和刷新行为明确时。
一个实用的结构如下:
- 认证协调员: 启动登录,跟踪状态,处理回调。
- 令牌服务: 通过本机安全存储存储令牌,而不是浏览器存储。
- API 客户端: 附加访问令牌,重试一次刷新,然后在不可恢复的失败时强制注销。
- 政策感知后端: 将令牌声明映射到服务器端授权检查。
您还希望会话工具与混合应用程序生命周期相匹配。如果您正在评估该层的选项,请将__CAPGO_KEEP_0__用于安全会话管理的插件进行比较。 Capacitor 插件用于安全会话管理 重要的是不是语法。它是保持刷新集中化,以便每个屏幕不需要自己发明会话行为。
需要额外小心的 Electron 模式
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 需要更严格的边界。将令牌交换和安全存储放在主进程中时尽可能。将窄 IPC 方法暴露给渲染器,而不是将原始令牌传递给渲染器并希望它表现良好。
桌面应用程序感觉更可控。将这种感觉视为风险,而不是保证。
避免这些捷径:
不要将令牌存储在渲染器可访问的本地存储中
桌面应用程序感觉更可控。将这种感觉视为风险,而不是保证。
- 避免这些捷径: 如果可以避免的话。
- 不要让每个窗口共享广泛的认证上下文 而不检查窗口目的和会话生存时间。
- 不要过度信任预加载脚本 作为进程隔离和明确API边界的替代品。
运营可见性也很重要。根据 Splunk的应用安全需求概述, 应用程序授权应与持续活动监控和日志记录集成,Benchmark数据中提到,组织可以通过主动记录和监控授权事件 在15分钟内检测到95%的未经授权访问尝试。实际上,这意味着记录被拒绝的操作、令牌刷新失败、角色更改、同意撤销和异常资源访问模式。
如果您的发布过程包括混合应用更新,那么在这个生态系统中的一种选择是 Capgo让 Capacitor 和 Electron 应用程序获得签名的实时更新。然而,这并没有为您实现授权,但它确实会影响您可以快速部署修复的速度,当 auth 逻辑、重定向处理或会话 code 需要紧急修复时。
您的安全应用程序授权之旅
良好的应用程序授权不是一个决定。它是一系列需要共同坚持的决定。您正确地验证用户,请求所需的访问权限,通过安全流程如 OAuth 2.0 与 PKCE 交换令牌,存储机密在合适的位置,并在服务器端每次强制执行权限。
对于 Capacitor 和 Electron 团队来说,最重要的是边缘的纪律。浏览器时代的捷径在接触本机存储、深度链接、桌面进程边界或应用程序审查要求时不会幸免。通常不做任何奇怪的事情的团队只是关于范围、会话处理、服务器端检查和审计一致。
如果您的当前授权设置感到混乱,这是正常的。从一个边界开始,逐步加紧。修复流程。修复存储。将访问规则从 UI 中移除。添加日志以告知您何时有人要求他们不应该拥有的东西。
这就是安全应用程序授权变得可管理的方式。理论上没有变得简单。 code 中更安全。
Capgo 帮助团队将修复推送到 Capacitor 和 Electron 应用程序,而无需等待商店审查,这对于需要快速修复认证流程、令牌处理或会话错误的情况至关重要。如果您的团队想要更紧密的控制跨平台发布、目标发布和回滚支持, Capgo 值得与您的应用程序授权堆栈一起评估。