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

瀏覽器相容性