帮助用户更顺畅地采用通行密钥

发布时间:2025 年 5 月 9 日

通行密钥可提供强大的身份验证机制,可防范钓鱼式攻击。不过,要让用户采用这些功能,可能会遇到阻碍。借助通行密钥升级功能,只要用户已为您的网站保存了密码,您就可以在适当的时机为他们创建通行密钥。条件创建(用于启用通行密钥升级)是 WebAuthn 规范的一部分。

运作方式

为了帮助用户更方便地采用通行密钥,请使用一项名为有条件创建的 WebAuthn API 功能。借助条件式创建,您的网站可以为用户请求通行密钥,而无需用户执行任何操作。

当满足以下条件时,此流程才会有效:

  • 用户在默认的密码管理工具中保存了密码。
  • 密码最近曾被使用。理想情况下,应在基于密码的登录成功后立即调用有条件创建。

如果同时满足这两个条件,您可以通过调用 Conditional Create 请求密码管理工具为用户创建通行密钥。成功创建通行密钥后,系统会根据密码管理工具向用户发送通知。

带有条件创建的通行密钥请求流程。

兼容性

Chrome 136 桌面版开始,支持条件式创建。

实现有条件创建

通行密钥升级基于一项名为有条件创建的 WebAuthn API 功能。这些是将 mediation 参数设置为 "conditional" 的常规 WebAuthn create() 请求,其运作方式与 get() 请求的通行密钥自动填充功能类似。

在用户使用密码登录后,使用基于条件的创建操作。升级是否成功取决于密码管理工具是否满足特定条件。这些条件可能会因密码管理工具而异,并且可能会随时间推移而发生变化。例如,在 Chrome 中使用 Google 密码管理工具 (GPM) 时,用户必须最近使用已保存的网站密码登录过。

如果浏览器成功创建通行密钥,则会返回公钥凭据。将此凭据发送到您的后端,以完成注册并启用日后的身份验证。

功能检测

您可以通过调用 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:通行密钥提供程序中已存在通行密钥。
  • NotAllowedError:创建通行密钥不符合条件。
  • AbortError:WebAuthn 调用已被中止。

在这些情况下,显示错误可能会让用户感到困惑,因为浏览器会静默处理这些错误:它仅在成功时显示通知,失败不会触发可见消息。

注册通行密钥失败时的信号

如果通行密钥已创建,但未能在服务器上注册,用户将会遇到登录失败的情况。如果通行密钥提供程序和服务器之间的通行密钥列表不一致,就可能会出现这种情况。

为避免出现这种情况,请使用 Signal API 使其保持一致

不支持从无密码登录升级

此时,系统会要求用户输入有效的密码,然后才能有条件地创建通行密钥。这意味着,魔法链接、电话号码验证或身份联合等无密码登录方法不符合条件。

摘要

通行密钥升级可以加快您网站上通行密钥的采用速度,帮助您让网站用户从密码过渡到更安全的身份验证方法。

如需详细了解通行密钥,请先参阅使用通行密钥实现无密码登录