发布时间:2025 年 5 月 9 日
通行密钥提供强大的防钓鱼式攻击的身份验证机制。不过,让用户采用这些功能可能会带来阻力。借助自动创建通行密钥功能,您可以在适当的时机为用户创建通行密钥,前提是用户已为您的网站保存密码。条件创建是 WebAuthn 规范的一部分,可实现自动创建通行密钥。
运作方式
为了帮助用户更方便地采用通行密钥,请使用名为条件创建的 WebAuthn API 功能。借助条件创建功能,您的网站可以为用户请求通行密钥,而无需用户执行任何操作。
当满足以下条件时,此流程会正常运行:
- 用户在默认密码管理工具中保存了密码。
- 该密码最近曾被使用过。理想情况下,在基于密码的登录成功后立即调用条件创建。
如果这两个条件都满足,您可以调用条件创建来请求密码管理器为用户创建通行密钥。成功创建通行密钥后,系统会根据密码管理器的不同通知用户。
兼容性
macOS 上的 Safari 和 iOS 上的所有浏览器以及桌面版 Chrome 和 Android 版 Chrome 均支持有条件创建。
实现有条件创建
自动创建通行密钥基于一项名为条件创建的 WebAuthn API 功能。这些是常规 WebAuthn create()
请求,其中 mediation
参数设置为 "conditional"
,这与 get()
请求的通行密钥自动填充类似。
在用户使用密码登录后,使用条件式创建。创建是否成功取决于密码管理器以及是否满足某些条件。这些条件可能因密码管理工具而异,并且可能会随时间推移而发生变化。例如,在搭载 Google 密码管理工具 (GPM) 的 Chrome 中,用户必须最近使用保存的网站密码登录过。
如果浏览器成功创建通行密钥,则会返回公钥凭据。将此凭据发送到您的后端,以完成注册并启用未来的身份验证。
功能检测
您可以通过调用 PublicKeyCredential.getClientCapabilities()
来确定浏览器是否支持有条件创建。查看返回的对象是否包含 conditionalCreate
属性的 true
。
if (window.PublicKeyCredential && PublicKeyCredential.getClientCapabilities) {
const capabilities = await PublicKeyCredential.getClientCapabilities();
if (capabilities.conditionalCreate) {
// Conditional create is available
}
}
如果 getClientCapabilities
不可用,则条件性创建也不可用。
有条件地创建通行密钥
如需执行自动创建通行密钥操作,请调用 navigator.credentials.create()
,但使用 mediation: "conditional"
,如下所示。
const cred = await navigator.credentials.create({
publicKey: options,
// Request conditional creation
mediation: 'conditional'
});
您应在用户登录后立即使用自动通行密钥创建功能,这样才能最大限度地满足密码管理器的自动创建条件。
您可以将生成的公钥凭据发送到服务器,以验证并注册通行密钥。在服务器上,确保用户已登录。
注意事项
条件创建本身并不难实现,但在将此功能实际集成到现有系统中时,需要注意以下几点。
在服务器上忽略用户存在性和用户验证
注册响应将“用户存在”和“用户已验证”都返回为 false
,因此服务器应在凭据验证期间忽略这些标志。
在执行自动通行密钥创建之前中止正在进行的 WebAuthn 调用
当 RP 希望用户使用通行密钥或密码登录时,执行条件性获取是最佳选择。这可能会导致条件性 get 调用在执行条件性创建之前被取消。
为此,您需要使用 AbortController
并调用 .abort()
。
// To abort a WebAuthn call, instantiate an AbortController.
const controller = new AbortController();
const cred = await navigator.credentials.get({
publicKey: options,
signal: controller.signal,
// Request conditional get
mediation: 'conditional'
});
// Abort the call
controller.abort();
优雅地忽略异常
执行有条件的通行密钥创建时,在以下几种情况下,您应忽略异常:
InvalidStateError
:通行密钥提供程序中已存在通行密钥(别忘了指定excludeCredentials
)。NotAllowedError
:创建通行密钥不符合条件。AbortError
:WebAuthn 调用已中止。
在这些情况下显示错误可能会让用户感到困惑,因为浏览器会以静默方式处理这些错误:仅在成功时显示通知,而失败不会触发可见的消息。
在注册通行密钥失败时发出信号
如果通行密钥已创建但未能成功在服务器上注册,用户将无法成功登录。如果通行密钥提供方和服务器之间的通行密钥列表不一致,可能会发生这种情况。
为避免这种情况,请使用 Signal API 来保持它们的一致性。
不支持从无密码登录升级
此时,有条件地创建通行密钥需要用户输入有效密码。这意味着,无密码登录方法(例如魔法链接、电话号码验证或身份联合)不符合此条件。
摘要
自动创建通行密钥有助于加快通行密钥在您网站上的普及,帮助您的网站用户从密码过渡到更安全的身份验证方法。
如需详细了解通行密钥,请先参阅使用通行密钥进行无密码登录。