Credential Management API 功能检测检查

摘要

WebAuthn 通过将基于公钥凭据的身份验证引入 Web 来提高安全性,Chrome、Firefox 和 Edge 即将支持 WebAuthn(采用更新后的规范)。它添加了一种新的 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(Web 身份验证)会向 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。