Credential Management API 功能检测检查

摘要

WebAuthn 将基于公钥凭据的身份验证引入到 Web 中,以帮助提高安全性,并且很快将在 Chrome、Firefox 和 Edge 中(更新了规范)支持。不过,它添加了一种新的 Credential 对象,但可能会导致使用 Credential Management API 的网站无法正常运行,而网站无法通过功能检测其使用的具体凭据类型。

如果您当前这样做是为了进行功能检测

if (navigator.credentials && navigator.credentials.preventSilentAccess) {
    // use CM API
}

改为执行以下操作

if (window.PasswordCredential || window.FederatedCredential) {
    // Call navigator.credentials.get() to retrieve stored
    // PasswordCredentials or FederatedCredentials.
}

if (window.PasswordCredential) {
    // Get/Store PasswordCredential
}

if (window.FederatedCredential) {
    // Get/Store FederatedCredential
}

if (navigator.credentials && navigator.credentials.preventSilentAccess) {
    // Call navigator.credentials.preventSilentAccess()
}

您可以参阅对示例代码进行的更改

请继续阅读以了解详情。

什么是 Credential Management API

Credential Management API (CM API) 允许网站以编程方式访问用户代理的凭据存储区,以便存储/检索调用方的用户凭据。

基本 API 包括:

  • navigator.credentials.get()
  • navigator.credentials.store()
  • navigator.credentials.create()
  • navigator.credentials.preventSilentAccess()

原始 CM API 规范定义了 2 种凭据类型:

  • PasswordCredential
  • FederatedCredential

PasswordCredential 是包含用户 ID 和密码的凭据。FederatedCredential 是包含用户 ID 和表示身份提供方的字符串的凭据。

有了这 2 种凭据,网站就可以:

  • 允许用户在登录后立即使用先前保存的基于密码的凭据或联合凭据登录(自动登录);
  • 存储用户登录时使用的基于密码的凭据或联合凭据,
  • 使用户的登录凭据保持最新状态(例如在更改密码后)

什么是 WebAuthn

WebAuthn(网络身份验证)会向 CM API 添加公钥凭据。例如,它为网站提供了使用符合 FIDO 2.0 标准的身份验证器设备实现双重身份验证的标准化方法。

在技术层面上,WebAuthn 使用 PublicKeyCredential 接口扩展 CM API。

具体问题

之前,我们一直在指导开发者使用以下代码对 CM API 进行功能检测:

if (navigator.credentials && navigator.credentials.preventSilentAccess) {
  // Use CM API
}

But as you can see from the descriptions above, the `navigator.credentials` is
now expanded to support public-key credentials in addition to password
credentials and federated credentials.

The problem is that user agents don't necessarily support all kinds of
credentials. If you continue feature detect using `navigator.credentials`, your
website may break when you are using a certain credential type not supported by
the browser.

**Supported credential types by browsers**
<table class="properties with-heading-tint"><tbody><tr>
<th></th>
<th>PasswordCredential / FederatedCredential</th>
<th>PublicKeyCredential</th>
</tr><tr><th>Chrome
</th><td>Available
</td><td>In development
</td></tr><tr><th>Firefox
</th><td>N/A
</td><td>Aiming to ship on 60
</td></tr><tr><th>Edge
</th><td>N/A
</td><td>Implemented with <a href="https://blogs.windows.com/msedgedev/2016/04/12/a-world-without-passwords-windows-hello-in-microsoft-edge/">older API</a>. New API (navigator.credentials) coming soon.
</td></tr></tbody></table>


## The solution
You can avoid this by modifying feature detection code as follows to explicitly
test for the credential type that you intend to use.

```js
if (window.PasswordCredential || window.FederatedCredential) {
    // Call navigator.credentials.get() to retrieve stored
    // PasswordCredentials or FederatedCredentials.
}

if (window.PasswordCredential) {
    // Get/Store PasswordCredential
}

if (window.FederatedCredential) {
    // Get/Store FederatedCredential
}

if (navigator.credentials && navigator.credentials.preventSilentAccess) {
    // Call navigator.credentials.preventSilentAccess()
}

您可以参阅对示例代码所做的实际更改

下面介绍了如何检测 WebAuthn 中添加的 PublicKeyCredential,以供参考:

if (window.PublicKeyCredential) {
    // use CM API with PublicKeyCredential added in the WebAuthn spec
}

时间轴

WebAuthn 最早的实现是 Firefox,我们计划在 2018 年 5 月初左右实现稳定

最后

如果您有任何疑问,请发送至 @agektmr 或 agektmr@chromium.org。