CredentialsContainer: get() 方法

Baseline 广泛可用 *

此功能已成熟,并可在多种设备和浏览器版本上使用。自 2019 年 9 月以来,它已在各种浏览器中可用。

* 此特性的某些部分可能存在不同级别的支持。

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

CredentialsContainer 接口的 get() 方法返回一个 Promise,该 Promise 会解析为一个 凭证,然后可用于将用户认证到网站。

该方法接受一个可选的 options 参数,其中可以包含:

  • 一个 mediation 属性,指示用户应该以何种方式以及是否应该参与操作。这控制着,例如,网站是否可以使用存储的凭证静默登录用户。
  • 一个 signal 属性,允许使用 AbortController 来取消操作。
  • 一个或多个属性 — passwordfederatedidentityotppublicKey — 指示所请求的 凭证类型。如果设置,这些属性的值将包含浏览器查找相应类型的凭证所需的任何参数。

API 总是解析为一个凭证或 null。如果有多个凭证可用并且允许用户调解,则浏览器会要求用户选择一个凭证。

语法

js
get()
get(options)

参数

options 可选

一个包含请求选项的对象。它可以包含以下属性:

mediation 可选

一个字符串,指示用户是否需要为每次访问客户端应用程序而登录。该值可以是以下之一:

"conditional"

发现的凭证会以非模态对话框的形式呈现给用户,并显示请求凭证的来源。实际上,这意味着自动填充可用凭证;有关如何使用此功能,请参阅 使用表单自动填充通过通行密钥登录PublicKeyCredential.isConditionalMediationAvailable() 也提供了一些有用的信息。

"optional"

如果凭证可以为给定操作在没有用户调解的情况下交接,它们就会被交接,从而实现无需用户调解的自动重新认证。如果需要用户调解,用户代理将要求用户进行身份验证。此值适用于您有理由相信用户不会对看到登录对话框感到惊讶或困惑的情况 — 例如,在不自动登录用户的网站上,当用户刚点击“登录/注册”按钮时。

"required"

将始终要求用户进行身份验证。此值适用于您想要强制用户进行身份验证的情况 — 例如,当执行敏感操作(如确认信用卡付款)或切换用户时,您希望用户重新进行身份验证。

"silent"

不会要求用户进行身份验证。用户代理将自动重新认证用户,并在可能的情况下登录。如果需要同意,Promise 将解析为 null。此值适用于您希望尽可能在用户访问 Web 应用程序时自动登录用户,但如果不行,您不想向他们显示一个令人困惑的登录对话框。相反,您希望等待他们显式单击“登录/注册”按钮。

默认值为 "optional"

注意: 对于 联邦身份验证 (FedCM API) 请求,mediation 值为 optionalsilent 可能会导致尝试 自动重新认证。是否发生这种情况会通过 发送到 IdP 的 id_assertion_endpointis_auto_selected 参数 在验证时传达给身份提供商 (IdP),并通过 IdentityCredential.isAutoSelected 属性传达给依赖方 (RP)。这对于性能评估、安全要求(IdP 可能希望拒绝自动重新认证请求并始终要求用户调解)和通用用户体验(IdP 或 RP 可能希望为自动登录和非自动登录体验提供不同的用户体验)非常有用。

signal 可选

一个 AbortSignal 对象实例,允许中止正在进行的 get() 操作。中止的操作可能会正常完成(通常在操作完成后收到中止信号)或以 AbortError DOMException 拒绝。

password 可选

此选项要求浏览器检索存储的 密码,作为 PasswordCredential 对象。它是一个布尔值。

identity 可选

此选项要求浏览器使用 Federated Credential Management API 检索 联合身份凭证,作为 IdentityCredential 对象。

此选项的值是一个 IdentityCredentialRequestOptions 对象,其中包含网站想要使用的特定身份提供商的详细信息。

federated 可选

此选项要求浏览器检索 联合身份凭证,作为 FederatedCredential 对象。此接口已被废弃,开发者应优先使用 identity 选项(如果可用)。

此选项的值是一个具有以下属性的对象:

protocols

一个字符串数组,表示请求凭证的联合身份提供商的协议(例如,"openidconnect")。

providers

一个字符串数组,表示凭证的联合身份提供商(例如 "https://#""https://#")。

otp 可选

此选项要求浏览器检索 一次性密码 (OTP),作为 OTPCredential 对象。

此选项的值是一个字符串数组,其中只能包含字符串值 "sms"

publicKey 可选

此选项要求浏览器检索一个使用 Web Authentication API 签名的 断言,作为 PublicKeyCredential

此选项的值是一个 PublicKeyCredentialRequestOptions 对象。

返回值

一个 Promise,它解析为以下 Credential 的一个子类:

如果在 get() 调用中指定了 条件调解,则会显示浏览器 UI 对话框,并且 Promise 会保持挂起状态,直到用户从可用自动填充建议中选择一个帐户进行登录。

  • 如果用户在浏览器 UI 对话框之外执行了某个操作,对话框将关闭,而不会解析或拒绝 Promise,也不会导致用户可见的错误情况。
  • 如果用户选择了凭证,则相关的 PublicKeyCredential 将返回给调用者。

如果无法明确获得单个凭证,则 Promise 将解析为 null

异常

AbortError DOMException

请求被与此方法 signal 选项关联的 AbortControllerabort() 方法调用中止。

IdentityCredentialError

在请求 IdentityCredential 时,对 ID 断言端点 的请求无法验证身份验证,并以包含原因信息的错误响应拒绝。

NetworkError DOMException

在请求 IdentityCredential 时,身份提供商 (IdP) 未在 60 秒内响应、提供的凭证无效/未找到,或者 IdP 的浏览器登录状态设置为 "logged-out"(有关 FedCM 登录状态的更多信息,请参阅 使用登录状态 API 更新登录状态)。在后一种情况下,可能会延迟拒绝以避免将 IdP 登录状态泄露给 RP。

NotAllowedError DOMException

在以下任一情况抛出:

SecurityError DOMException

调用域不是有效域。

示例

检索联合身份凭证

依赖方可以调用 get() 并使用 identity 选项来请求用户通过身份提供商 (IdP) 通过身份联合登录依赖方。典型的请求如下所示:

js
async function signIn() {
  const identityCredential = await navigator.credentials.get({
    identity: {
      providers: [
        {
          configURL: "https://accounts.idp.example/config.json",
          clientId: "********",
          nonce: "******",
        },
      ],
    },
  });
}

有关此功能的更多信息,请查看 Federated Credential Management (FedCM) API。此调用将启动 FedCM 登录流程 中描述的登录流程。

一个包含 contextloginHint 扩展的类似调用如下所示:

js
async function signIn() {
  const identityCredential = await navigator.credentials.get({
    identity: {
      context: "signup",
      providers: [
        {
          configURL: "https://accounts.idp.example/config.json",
          clientId: "********",
          nonce: "******",
          loginHint: "user1@example.com",
        },
      ],
    },
  });
}

如果 IdP 无法验证对 ID 断言端点 的请求,它将拒绝从 CredentialsContainer.get() 返回的 Promise。

js
async function signIn() {
  try {
    const identityCredential = await navigator.credentials.get({
      identity: {
        providers: [
          {
            configURL: "https://accounts.idp.example/config.json",
            clientId: "********",
            nonce: "******",
          },
        ],
      },
    });
  } catch (e) {
    // Handle the error in some way, for example provide information
    // to help the user succeed in a future sign-in attempt
    console.error(e);
  }
}

检索公钥凭证

以下代码段显示了一个典型的带有 WebAuthn publicKey 选项的 get() 调用:

js
const publicKey = {
  challenge: new Uint8Array([139, 66, 181, 87, 7, 203 /* ,… */]),
  rpId: "acme.com",
  allowCredentials: [
    {
      type: "public-key",
      id: new Uint8Array([64, 66, 25, 78, 168, 226, 174 /* ,… */]),
    },
  ],
  userVerification: "required",
};

navigator.credentials.get({ publicKey });

成功的 get() 调用返回一个 Promise,该 Promise 解析为 PublicKeyCredential 对象实例,该实例代表之前通过 WebAuthn create() 创建的公钥凭证,现已用于对用户进行身份验证。其 PublicKeyCredential.response 属性包含一个 AuthenticatorAssertionResponse 对象,该对象提供了对几个有用信息的访问,包括身份验证器数据、签名和用户句柄。

js
navigator.credentials.get({ publicKey }).then((publicKeyCredential) => {
  const response = publicKeyCredential.response;

  // Access authenticator data ArrayBuffer
  const authenticatorData = response.authenticatorData;

  // Access client JSON
  const clientJSON = response.clientDataJSON;

  // Access signature ArrayBuffer
  const signature = response.signature;

  // Access userHandle ArrayBuffer
  const userHandle = response.userHandle;
});

其中一些数据需要存储在服务器上 — 例如 signature,以提供身份验证器拥有用于创建凭证的真实私钥的证据,以及 userHandle,用于将用户与凭证、登录尝试和其他数据关联。

有关整个流程的工作原理,请参阅 Authenticating a user

检索一次性密码

下面的代码在 SMS 消息到达时触发浏览器的权限流程。如果授予权限,则 Promise 会解析为一个 OTPCredential 对象。然后,其中的 code 值被设置为一个 <input> 表单元素的值,该元素随后被提交。

js
navigator.credentials
  .get({
    otp: { transport: ["sms"] },
    signal: ac.signal,
  })
  .then((otp) => {
    input.value = otp.code;
    if (form) form.submit();
  })
  .catch((err) => {
    console.error(err);
  });

规范

规范
Credential Management Level 1
# dom-credentialscontainer-get

浏览器兼容性