See the original blog version in English here.

Passkeys Cheat Sheet — dev-focused WebAuthn reference. Trusted by Ally, Stanford CS & more.
WebAuthn 是 Passkeys 背后的现代标准。它不依赖于传统的密码,而是利用公钥加密技术,让用户可以通过包含生物识别(如指纹或面部识别)或物理安全密钥的 Passkeys 进行身份验证。这种转变不仅提高了安全性,还消除了密码管理的烦恼,从而大大改善了用户体验。
WebAuthn Level 3
标准引入了全新的客户端能力(可以通过浏览器 API getClientCapabilities()
获取),旨在为开发者和平台提供更多控制权和灵活性来实现 Passkeys。这些更新简化了在不同设备、浏览器和平台间集成 Passkeys 的流程,确保了更加顺畅一致的用户旅程。
在这篇文章中,我们将解答以下问题:
读完本文,你就能理解如何利用这些功能来打造符合现代用户期望、既无缝又安全的身份验证流程。
WebAuthn 客户端能力是一组特性,允许浏览器和平台传达它们支持哪些 WebAuthn 功能。简单来说,它们就像是一个“功能清单”,让网站了解用户设备上可用的身份验证方法和设置。这使得开发者能够根据客户端的能力来量身定制身份验证流程,从而确保更顺畅、更安全的用户体验。
例如,如果浏览器发出信号表示支持生物识别身份验证(如 Touch ID),开发者就可以设计登录流程,为用户提供使用指纹登录的选项。反之,如果浏览器不支持某些功能,开发者可以提供备用方案,比如密码或短信 OTP。在实际操作中,不支持或被中断的能力路径可能仍会表现为常规的浏览器错误,因此团队应将这些结果映射到明确的 WebAuthn 错误分类中。
WebAuthn Level 3 标准引入了多项全新的客户端能力,使 Passkeys 的实现更加灵活且对用户更友好。对
getClientCapabilities() API 调用的首次支持是在 Safari 17.4 中引入的。
为了检测浏览器中的支持情况,下面的代码片段会非常实用:
// Check if PublicKeyCredential is supported in the current browser if (typeof PublicKeyCredential === "undefined") { console.log("PublicKeyCredential is not supported in this browser."); } // Check if getClientCapabilities method exists on PublicKeyCredential if (typeof PublicKeyCredential.getClientCapabilities === "function") { try { let capabilities = await PublicKeyCredential.getClientCapabilities(); console.log(capabilities); } catch (error) { console.error("Error getting client capabilities:", error); } } else { console.log("getClientCapabilities is not supported in this browser"); }
getClientCapabilities()
允许网站和应用查询客户端(例如浏览器或设备),以确定其支持哪些 WebAuthn 功能。通过了解客户端的能力,开发者可以优化身份验证流程以利用可用功能(例如生物识别身份验证),并在缺少某些功能时提供替代方法。
Subscribe to our Passkeys Substack for the latest news.
下面我们来深入了解一下 WebAuthn 客户端能力及其对 Passkey 集成的影响:
conditionalCreate
支持基于特定条件自动创建 Passkey。如果密码管理器具有相应支持,应用程序可以使用此能力在密码自动填充期间自动创建 Passkey。此功能通过自动将用户从密码过渡到 Passkeys,有助于推动 Passkeys 的采用和后续使用。
与 conditionalCreate 类似,conditionalGet
能够自动触发 Passkey 登录。这在需要启用最佳 Passkey
UX 的场景中非常有用,它不仅让登录实现了无密码化,还实现了无用户名化(用户只需在弹窗/下拉菜单中点击选定的 Passkey 即可完成身份验证)。通过使用此能力,开发者可以确保仅在合适的时候进行 Passkey 身份验证,从而最大限度地减少不必要的提示并提升用户体验。
hybridTransport
确保 Passkeys 可以在不同设备上使用,实现无缝的跨设备身份验证(通过二维码和蓝牙)。例如,用户可以使用存储在智能手机上的 Passkey 登录其桌面设备上的服务。这种能力允许用户安全地进行身份验证,而无需为每台设备手动转移 Passkeys 或依赖传统的登录方法,从而营造统一的身份验证体验。
平台身份验证器(例如 Windows Hello、Face ID 或 Touch ID)直接内置在设备中。它们通过允许用户使用生物识别或其他设备原生方法(例如 PIN 码图案)进行身份验证,提供更快、更流畅且更安全的 Passkey 体验。
Become part of our Passkeys Community for updates & support.
userVerifyingPlatformAuthenticator
确保 Passkey 身份验证涉及用户验证环节,例如主动扫描指纹或面部识别,从而提供额外的安全层。
relatedOrigins
能力允许在同一组织拥有的不同域名(例如 amazon.com 和 amazon.de)之间进行无缝身份验证。举例来说,如果一家公司管理多个域名或拥有不同的子域名,用户只需登录一次即可访问所有资产,而无需在每个域名上重新进行身份验证。这种能力简化了用户体验,减少了摩擦,对于处于国际环境或拥有多服务平台的企业尤其有价值。
signalAllAcceptedCredentials(options)
方法提供给定用户的完整 WebAuthn 凭据 ID 列表。当用户经过身份验证时,WebAuthn 依赖方应优先使用此方法而不是
signalUnknownCredential(),因为此时不存在隐私泄露的风险。此方法提供了用户公钥凭据的全面概览,包括可能尚未在当前连接的身份验证器上更新的任何最新更改。
让我们来看一个例子。一个用户(userId: A)拥有 2 个 Passkeys,其凭据 ID 经过 Base64URL 编码为 X 和 Y。然后,用户在网络服务(example.com)的帐户设置中删除了 Passkey
X(因此公钥被删除)。现在,运行以下代码片段:
PublicKeyCredential.signalAllAcceptedCredentials({ rpId: "example.com", userId: "A", // WebAuthn User Handle, Base64URL. allAcceptedCredentialIds: ["Y"], });
如果在执行上述代码时身份验证器处于可用状态,则身份验证器会从未来的身份验证流程中删除或隐藏 Passkey X。但是,执行时可能并未连接身份验证器,因此建议依赖方应定期执行此代码,例如在每次登录时。
不在 allAcceptedCredentialIds
中的 Passkeys 将被删除或隐藏,这可能是不可逆的。因此,对于依赖方来说,确保有效的 WebAuthn 凭据 ID 永远不被从列表中删除至关重要。如果意外删除了有效的凭据 ID,依赖方应尽快在另一次
signalAllAcceptedCredentials(options)
调用中将其包含进去,以“取消隐藏”该 Passkey。如果 Passkey 不是被隐藏而是被删除了,那么就很难恢复了。
Experiment with passkey flows in the Passkeys Debugger.
signalCurrentUserDetails(options)
方法会发出用户当前姓名和 WebAuthn 显示名称的信号。当调用
signalCurrentUserDetails(options) 时,客户端将按照一组定义的步骤执行此操作。
来看一个例子。具有 WebAuthn 用户 ID A
的用户在网站(example.com)的帐户设置中更新了其姓名。然后,依赖方可以运行以下代码:
PublicKeyCredential.signalCurrentUserDetails({ rpId: "example.com", userId: "A", // user ID, Base64URL. name: "New user name", displayName: "New display name", });
然后身份验证器会更新本地保存的 Passkey 元数据。最大的好处是,在未来的 Conditional UI(条件 UI)/ Passkey 自动填充请求中,Conditional UI 选择 / 下拉菜单将显示更新后的姓名和 WebAuthn 显示名称。
signalUnknownCredential(options)
方法发出信号,表示 WebAuthn 依赖方无法识别某个 WebAuthn 凭据 ID,例如,如果 Passkey 被用户删除了。与
signalAllAcceptedCredentials(options)
不同,此方法不需要提供完整的已接受凭据 ID 列表和 WebAuthn 用户句柄 (User
Handle),从而防止了向未经过身份验证的调用者发生潜在的隐私泄露。
来看一个例子。用户在网站(example.com)的帐户设置中删除了凭据 ID 为 X
的 Passkey(因此公钥被删除)。但是,私钥仍然在用户的设备上可用。这意味着在未来的
Conditional UI / Passkey 自动填充登录请求(使用空的
allowCredentials
列表)中,仍可以选择该 Passkey。不过登录尝试会失败,因为公钥已被删除,所以依赖方应该运行:
PublicKeyCredential.signalUnknownCredential({ rpId: "example.com", credentialId: "X", // credential ID the user just tried, Base64URL });
然后,身份验证器将从未来的身份验证流程中删除或隐藏凭据 ID 为 X 的 Passkey。
由于 WebAuthn Level 3 标准仍处于草案状态,这些新客户端能力的采用尚未完全普及。不同的浏览器正在逐步实现这些功能,但支持情况各不相同。以下是上面提到的主要浏览器的最新可用性概览:
| 浏览器 | 支持客户端能力的版本 | 备注 |
|---|---|---|
| Chrome | 133 | Chrome 平台状态 & Chromium Bug 追踪器 |
| Safari | 17.4+ | 首个交付 getClientCapabilities() 的浏览器。截至 2024 年 10 月,Safari 支持的功能包括 conditionalCreate、conditionalMediation、hybridTransport、passkeyPlatformAuthenticator 和 userVerifyingPlatformAuthenticator。 |
| Edge | 133 | 基于 Chromium 133。Chromium Bug 追踪器 |
| Firefox | 135 | Mozilla 已开始在 Firefox 135 及更高版本中实现 WebAuthn Level 3 客户端能力。 |
随着 Level
3 的成熟以及更多浏览器交付这些功能,采用步伐可能会加快。如果你想了解目前有多少用户可以利用
getClientCapabilities(),你可以使用免费的
State of Passkeys
查看真实世界的数据。密切关注浏览器发布说明和相关文档,以便在其发展过程中规划更广泛的兼容性。
See how many people actually use passkeys.
作为一名开发者,你可能会问这些新的 WebAuthn 客户端能力检测对你意味着什么,以及你应该如何在应用中使用它们。在下文中,你会找到有关如何使用它们的建议。
但是,请注意并非所有浏览器都已支持 getClientCapabilities()
API 调用(截至 2024 年 11 月)。在所有浏览器迎头赶上之前,这里
提供了一个 polyfill 可供使用。
在代码早期(即页面加载 / 身份验证流程的开始)使用 getClientCapabilities()
来检测客户端支持的功能。这将使你能够动态自定义体验,并提供在设备 / 浏览器上有效的 Passkey 功能,例如在支持时推动平台身份验证,或在不支持时提供替代方法(例如短信 OTP 或硬件安全密钥)。
如果你将 Passkeys 添加到目前使用密码的网站 / 应用中,conditionalCreate
功能可以成为提高 Passkeys 采用率的真正助推器。在后台,当使用合适的凭据管理器(截至 2024 年 10 月仅有
Apple Passwords
支持)自动填充密码时,将自动生成一个 Passkey,并在未来的自动填充中优先使用。
为了不仅拥有较高的 Passkeys 采用率,还拥有较高的 Passkeys 登录使用率,请尝试通过检查
conditionalGet 来确定设备 / 浏览器是否可以使用 Conditional UI /
Passkey 自动填充。通过这种方式,你将促使用户使用已创建的 Passkey 进行登录,因为它是操作系统 / 浏览器主动建议的,并且比自动填充密码所需的精力更少。
利用 hybridTransport
实现跨设备身份验证(通过二维码和蓝牙),允许用户从智能手机无缝登录,即使用户正在桌面上访问你的服务。
WebAuthn 客户端能力在解决当前存在的 Passkey 痛点方面迈出了重要的一步。在这篇文章中,我们解答了有关 WebAuthn 客户端能力的关键问题:
getClientCapabilities、conditionalCreate、hybridTransport 等。我们鼓励你探索新的 WebAuthn Level 3 功能,并随时了解它们在各大浏览器中的采用情况。如果你希望实现 Passkeys 并利用这些高级能力,随时联系我们以获取专业的指导和支持。
在页面加载或身份验证流程的早期调用 getClientCapabilities() 以动态检测受支持的功能。这让你能够在支持时提供平台身份验证,或在不支持时回退到短信 OTP 或硬件安全密钥等替代方案。
signalAllAcceptedCredentials 需要完整的有效凭据 ID 列表和 WebAuthn 用户句柄 (User Handle),因此仅应在用户通过身份验证时调用,以避免隐私泄露。signalUnknownCredential 发出单个未识别凭据 ID 的信号且无需完整列表,因此在登录尝试失败等未经过身份验证的场景中调用也是安全的。
relatedOrigins 能力允许在同一组织拥有的不同域名(如 amazon.com 和 amazon.de)之间进行无缝的身份验证。用户只需登录一次即可访问所有资产,无需在每个域名上重新身份验证,从而减少了在国际化或多服务环境中的摩擦。
截至 2024 年 11 月,并非所有浏览器都支持 getClientCapabilities(),因此你可以使用 github.com/MasterKale/webauthn-polyfills 上提供的 polyfill 作为权宜之计。随着 WebAuthn Level 3 标准的成熟以及 Chrome 133、Edge 133、Firefox 135 和 Safari 17.4 的陆续支持,采用率预计将加速增长。
Related Articles
Table of Contents