PublicKeyCredential:signalUnknownCredential() 静态方法

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

安全上下文: 此功能仅在安全上下文(HTTPS)中可用,且支持此功能的浏览器数量有限。

PublicKeyCredential 接口的 signalUnknownCredential() 静态方法会告知认证器,凭证 ID 未被 信赖方 (RP) 服务器识别。

这允许认证器删除 RP 不允许的凭证,例如已删除帐户的凭证,或者在认证器上创建和存储但未在服务器上正确更新的帐户的凭证。通常,在登录因 RP 无法获取帐户详细信息而失败后会调用此方法。即使当前用户未通过身份验证,也可以使用它,因为它不会暴露敏感信息。

语法

js
signalUnknownCredential(options)

参数

options

一个代表未知凭证的对象,其中包含以下属性:

credentialId

一个 base64url 编码的字符串,表示未被识别的凭证 ID

rpId

一个字符串,表示发送信号的 RP 的 ID

返回值

一个 Promise,解析为 undefined

异常

Promise 会因以下异常而拒绝

SecurityError DOMException

RP 域无效。

TypeError DOMException

credentialId 不是有效的 base64url 编码字符串。

描述

用户认证器中存储的关于可发现凭证(例如,passkey)的信息可能与 RP 服务器不同步。这通常发生在用户从 RP Web 应用中删除凭证但未更新认证器时。

当用户尝试使用可发现凭证登录时,系统会向用户显示认证器中的一组凭证供其选择,然后将选定的凭证返回给 RP Web 应用以进行登录。如果用户选择了一个已从 RP 服务器删除的凭证,则该凭证不会被识别,登录也会失败。这会给用户带来困惑的体验,因为他们期望只看到应该成功的凭证。

为了缓解这个问题,每次基于可发现凭证的登录失败时,都应该在 RP Web 应用上调用 signalUnknownCredential(),以告知认证器该凭证 ID 未被识别。

认证器如何处理此信息由其自行决定,但期望的做法是删除相关凭证,以避免认证器和信赖方之间存储的数据不匹配。

此外,如果 Web 应用能够在认证器上创建可发现凭证,但由于任何原因无法将凭证信息上传到服务器,也可能调用 signalUnknownCredential()

signalUnknownCredential() 可以在当前用户未通过身份验证时调用,因为它不会暴露敏感信息。

示例

通知未知凭证

在此示例中,通过 get() 调用尝试使用可发现凭证进行登录。凭证成功返回,凭证 ID 和负载存储在常量中。

通过 fetch() 请求将负载发送到 RP 服务器以登录用户,但由于 RP 不识别该用户(例如,因为该凭证先前已从 RP 删除),请求失败并返回 404 响应。

因此,我们调用 signalUnknownCredential() 方法,并将 rpId 和凭证 ID 传递给它,以告知认证器该凭证是 RP 未知的。然后,认证器应该删除该凭证,以免再次引起相同的问题。

js
const credential = await navigator.credentials.get({
  challenge: new Uint8Array([139, 66, 181, 87, 7, 203 /* … */]),
  rpId: "example.com",
  allowCredentials: [],
  // Empty allowCredentials list means only discoverable
  // credentials are presented to the user
});

// Retrieve base64url-encoded credential ID,
// such as "vI0qOggiE3OT01ZRWBYz5l4MEgU0c7PmAA"
const credID = credential.id;
// Retrieve payload to send to the RP server
const payload = credential.toJSON();

const result = await fetch("/login", {
  // fetch() options, will include the payload in the request body
});

// Detect authentication failure due to lack of the credential
if (result.status === 404) {
  if (PublicKeyCredential.signalUnknownCredential) {
    await PublicKeyCredential.signalUnknownCredential({
      rpId: "example.com",
      credentialId: credID,
    });
  } else {
    // Encourage the user to delete the credential from the authenticator
  }
}

规范

规范
Web Authentication:访问公钥凭证的 API - 第 3 级
# dom-publickeycredential-signalunknowncredential

浏览器兼容性

另见