Electron 与 Chrome 的 Passkey 实现差异及方案参考
在桌面端应用中,使用网页内嵌的 Passkey(WebAuthn)时,Electron 环境与标准 Google Chrome 浏览器在凭证隔离、存储策略以及跨应用共享上存在显著差异。
一、主流实现方式与限制对比(含 Electron vs Chrome 差异)
| 实现途径 / 环境 | 同源策略与嵌入模式 | 凭证存储与跨应用共享差异 (Win vs Mac) | 主要限制与约束 |
|---|---|---|---|
| 1. 标准 Google Chrome 浏览器 | 运行在 Chrome 原生内核中,严格受网页同源策略限制(HTTPS 且 Origin 匹配) | • 内置独立密码管理器:Chrome 实现了自己的密码管理器,Passkey 凭证通常注册并托管在 Chrome 自身的内部数据库或同步账号中。 • 隔离性:其他独立应用或第三方浏览器通常无法直接读取 Chrome 内部注册的 Passkey,反之亦然。 | • 强依赖 Chrome 自身的生态与账号同步体系。 • 无法直接与本地操作系统的底层安全元件(如 macOS 的 Secure Enclave 专属组)实现完全解耦的独占绑定。 |
2. Electron 原生平台认证器 (app.configureWebAuthn) | 运行在 Electron 的 Webview / BrowserWindow 内,严格受同源策略限制(要求 HTTPS 且 Origin 匹配) | • 平台差异与隔离: - macOS:调用系统底层安全芯片,强依赖带 Secure Enclave (SE) 的设备。凭证落在 App 专属的 Keychain Access Group 中,不同应用之间互相隔离、无法读取(例如 macOS 上其他应用注册的 Passkey 无法在此读取),且不依赖 iCloud「密码」同步。 - Windows:依赖 Windows Hello / TPM 芯片及系统级平台认证器。 | • 平台强依赖:无对应硬件(如无 SE 或无 TPM)的机型无法使用。 • 对 Electron 版本有硬门槛。 |
3. 原生 AS / 平台 Provider 方案 (如第三方封装库 vault12/electron-webauthn-mac 等原生 Hook/Addon) | 绕过标准 Webview 网页同源限制,由主进程或原生模块直接与系统认证服务交互 | • 走系统统一凭证库: - macOS:走 AuthenticationServices 平台 Provider,使用系统统一密码钥匙串 / iCloud 同步路径。- Windows:走系统凭证管理器 / Win32 WebAuthn API 封装。 | • 属于独立的 Native 扩展 / 桥接路径,与 Electron 内置的 configureWebAuthn 隔离。• 凭证会进入系统公共生态(如 iCloud 密码),无法做到应用专属沙箱隔离。 |
| 跳转到浏览器完成认证 | 使用在web已经实现的passkey,认证成功之后,callback回到应用(可以利用应用自己的customprotocol) | 需要一次跳转 |
通过上面的对比可以看出来,想要完全实现类似chrome的效果其实比较难,electron走在线页面主要是影响体验,所以这里对在线页面性能要求就比较高。如果选择原生,win上问题不会特别多,主要在于mac上的限制,浏览器注册在自己内部的其他应用无法读取,应用自己注册则要求iCloud 密码必须开启,这样就需要登录apple账号,在特定网络环境下限制比较多。
另外一个问题必须要提及的就是mac上开发的过程中。passkey关联域名需要与应用bundleId进行绑定,https://learn.microsoft.com/zh-cn/dotnet/maui/macios/universal-links?view=net-maui-10.0 https://expo.nodejs.cn/linking/ios-universal-links/ 文章中最重要的就是两个:
a. 域名关联
开发者后台启用关联域:
修改plist文件:
<key>com.apple.developer.associated-domains<key>
<array>
<string>applinks:recipe-app.com</string>
</array>
b. 创建关联域文件
这个主要是在passkey关联域的服务器需要配置一个文件,必须开放外网访问,apple cdn会访问验证后缓存到本地(首次发布后需要大概24左右生效)
https://domain.name/.well-known/apple-app-site-association
服务器返回的 Content-Type 为 application/json,不要进行redirect
{
"webcredentials": {
"apps": ["<APPLE_TEAM_ID>.<BUNDLE_ID>"]
}
}
二、Electron 版本演进与能力引入
这里为啥会提及electron的版本,主要原因还是在于electron在mac上的差异性,虽然electron的版本支持了passkey,但是由于mac钥匙串的特殊性,导致长时间mac上无法唤起touchid认证,所以这个方案变成主流了vault12/electron-webauthn-mac,electron官方也有很多issue,所以官方在目前几个版本实现了,从目前来看至少需要41.6.0
针对内置的 configureWebAuthn 方案,不同 Electron 版本的行为差异如下:
| 版本区间 | 功能状态 | 实测表现与注意事项 |
|---|---|---|
| < 41.5.0 | 尚无原生支持 | 网页路径不可用,无法调用内置 API,只能走原生 addon 或其他桥接方案。 |
| v41.5.0 | 首次对外暴露 API | API 可调用,具备安全芯片的机型上 isUVPAA 可为 true,但触发系统生物识别弹窗时可能会触发 SIGTRAP (Trace/BPT trap: 5) 崩溃。 |
| ≥ v41.6.0 | 线上可用推荐版本 | 修复了本地化字符串丢失导致的崩溃问题,API 及弹窗均可完整走完。 |
三、联调避坑与关键配置指南
在实际开发和打包过程中,需要特别注意以下几点:
1. 平台差异与环境适配 (Win vs Mac)
- macOS:需在应用配置文件(Entitlements)中正确配置
keychain-access-groups,且代码中app.configureWebAuthn传入的keychainAccessGroup必须与之保持一致(格式如:TEAMID.BUNDLEID.webauthn)。由于 macOS 的沙箱与钥匙串隔离机制,其他应用注册的 Passkey 无法被读取。 - Windows:依赖 Windows Hello 体系及相应的 TPM 硬件支持,打包和权限配置与 macOS 的 Keychain 机制不同,需确保系统已启用 WinHello(指纹、pin或者硬件USB密钥)并且运行环境满足。
- 通用环境:内置
configureWebAuthn路径必须在正确的 HTTPS 且同源的 Origin 下运行,不能直接通过file://协议加载页面。
2. 必选事件监听
主进程必须监听 select-webauthn-account 事件,否则在多账号或多凭证选择场景下会导致认证流程卡住或断言失败:
session.defaultSession.on('select-webauthn-account', (details, callback) => {
// 选择对应凭证的逻辑
callback(selectedCredentialId);
});
app.configureWebAuthn({
touchID: {
keychainAccessGroup: 'TEAMID.BUNDLEID.webauthn', // 须与 entitlements keychain-access-groups 一致
// promptReason?: string // 41.6+ 可覆盖弹窗文案
}
});
3. 必选事件监听
在实际开发过程中,mac上由于校验plist的问题和运行进程的问题,修改后直接打包测试。win上没有这个限制
下面是一些相关的issue
| 类型 | URL |
|---|---|
API configureWebAuthn | https://github.com/electron/electron/blob/main/docs/api/app.md#appconfigurewebauthnoptions-macos |
API select-webauthn-account | https://github.com/electron/electron/blob/main/docs/api/session.md#event-select-webauthn-account |
| Release 41.5.0 | https://github.com/electron/electron/releases/tag/v41.5.0 |
| Release 41.6.0 | https://github.com/electron/electron/releases/tag/v41.6.0 |
| PR 能力引入 #51255 | https://github.com/electron/electron/pull/51255 |
| PR 能力引入 #51412 | https://github.com/electron/electron/pull/51412 |
| PR 崩溃修复 #51592 | https://github.com/electron/electron/pull/51592 |
| PR 41 线回溯 #51604 | https://github.com/electron/electron/pull/51604 |
| PR platformPasskeys(未合)#51563 | https://github.com/electron/electron/pull/51563 |
| 对比:Vault12 原生 AS | https://github.com/vault12/electron-webauthn-mac |
| 标准 WebAuthn | https://www.w3.org/TR/webauthn-2/ |