在信賴方端導入含有 FedCM 的識別資訊解決方案

信賴方 (RP) 必須完成下列步驟,才能在網站上啟用 FedCM

在依賴方呼叫 FedCM API

IdP 設定和端點可用後,RP 即可呼叫 navigator.credentials.get(),要求允許使用者透過 IdP 登入 RP。

呼叫 API 前,請先確認使用者的瀏覽器是否支援 FedCM。如要檢查 FedCM 是否可用,請將這段程式碼包裝在 FedCM 實作項目周圍:

  if ('IdentityCredential' in window) {
    // If the feature is available, take action
  } else {
    // FedCM is not supported, use a different identity solution
  }

如要讓使用者在 RP 上使用 FedCM 登入 IdP,RP 可以呼叫 navigator.credentials.get()。從 Chrome 136 開始,RP 可以在單一 navigator.credentials.get() 呼叫中指定多個身分提供者陣列,藉此支援多個 IdP,例如:

  const credential = await navigator.credentials.get({
      identity: {
        // Specify the IdP (or multiple IdPs, supported from Chrome 136) this Relying Party supports
        providers: [
        {
              configURL: 'https://accounts.idp-1.example/config.json',
              clientId: '********'
        },
        {
          configURL: 'https://accounts.idp-2.example/config.json',
          clientId: '********'
        }]
      }
    },
  );
  const { token } = credential;
  
  // Get the current IdP's configURL to identify which provider the user is signed in with
  const currentIdpConfigUrl = credential.configURL;
  if (currentIdpConfigUrl === 'https://idp1.example/foo.json') {
    // handle the case where the user signed in with idp1
  } else if (currentIdpConfigUrl === 'https://idp2.example/bar.json') {
    // handle the case where the user signed in with idp2
    }

如要試用多個 IdP 功能,請使用 IdP1IdP2 登入。

背景資訊屬性

透過選用的 context 屬性,RP 可以修改 FedCM 對話方塊 UI 中的字串 (例如「登入 rp.example…」、「使用 idp.example…」),以配合預先定義的驗證情境。context 屬性可具有下列值:

  • signin (預設)
  • signup
  • use
圖表:說明 FedCM 對話方塊的 UI 元件。左上角會顯示圖示。圖示右側的內容元件會顯示「使用 IdP 登入 RP」訊息。底部是「繼續」按鈕,文字和背景顏色皆為自訂。
如何將品牌宣傳元素套用至 FedCM 對話方塊

舉例來說,將 context 設為 use 會產生以下訊息:

顯示自訂內容訊息的 FedCM 對話方塊:內容訊息顯示「使用」FedCM,而不是「登入」FedCM。
顯示自訂內容訊息的 FedCM 對話方塊。

瀏覽器會根據帳戶清單端點回應中是否存在 approved_clients,以不同方式處理註冊和登入用途。如果使用者已註冊 RP,瀏覽器就不會顯示揭露文字「如要繼續使用『...』,請登入帳戶」
providers 屬性會採用 IdentityProvider 物件陣列,這些物件具有下列屬性:

提供者屬性

providers 屬性會採用 IdentityProvider 物件陣列,其中包含下列屬性:

屬性 說明
configURL (必填) IdP 設定檔的完整路徑。
clientId (必填) IdP 核發的 RP 用戶端 ID。
loginHint (非必要) 指定login_hints帳戶端點提供的其中一個值,FedCM 對話方塊就會只顯示指定的帳戶。
domainHint (非必要) 指定domain_hints帳戶端點提供的其中一個值,FedCM 對話方塊就會只顯示指定的帳戶。
mode (非必要) 指定 FedCM 使用者介面模式的字串。這個屬性可能會顯示下列其中一個值:
  • "active":FedCM 提示必須由使用者互動 (例如點選按鈕) 啟動。
  • "passive":系統會啟動 FedCM 提示,不需使用者直接互動。
如要進一步瞭解主動模式和被動模式的差異,請參閱總覽頁面

注意:Chrome 132 以上版本支援 mode 參數。
fields (非必要) 字串陣列,指定 RP 需要 IdP 與其分享的使用者資訊 (「name」、「email」、「picture」)。
注意:Chrome 132 以上版本支援 Field API。
params (非必要) 自訂物件,可指定其他鍵/值參數:
  • scope:字串值,包含 RP 需要要求的其他權限,例如 "drive.readonly calendar.readonly"
  • nonce:隨機字串,確保系統針對這項特定要求發出回應。防範重送攻擊。
  • 其他自訂鍵/值參數。

注意:Chrome 132 以上版本支援 params

啟用模式

FedCM 支援不同的使用者體驗模式設定。 被動模式是預設模式,開發人員不需要進行設定。

如要在啟用模式下使用 FedCM,請按照下列步驟操作:

  1. 檢查使用者瀏覽器是否支援這項功能。
  2. 使用暫時性使用者手勢 (例如點選按鈕) 叫用 API。
  3. mode 參數傳遞至 API 呼叫:
  let supportsFedCmMode = false;
  try {
    navigator.credentials.get({
      identity: Object.defineProperty(
        // Check if this Chrome version supports the Mode API.
        {}, 'mode', {
          get: function () { supportsFedCmMode = true; }
        }
      )
    });
  } catch(e) {}

  if (supportsFedCmMode) {
    // The button mode is supported. Call the API with mode property:
    return await navigator.credentials.get({
      identity: {
        providers: [{
          configURL: 'https://idp.example/config.json',
          clientId: '123',
        }],
        // The 'mode' value defines the UX mode of FedCM.
        // - 'active': Must be initiated by user interaction (e.g., clicking a button).
        // - 'passive': Can be initiated without direct user interaction.
        mode: 'active'
      }
    });
  }

如要試用正常模式,請參閱這份示範

啟用模式下的自訂圖示

在主動模式下,IdP 可直接在用戶端中繼資料端點回應中加入 RP 的官方標誌圖示。RP 必須預先提供品牌資料。

從跨來源 iframe 呼叫 FedCM

如果父框架允許,即可使用 identity-credentials-get 權限政策,從跨來源 iframe 內叫用 FedCM。如要這麼做,請將 allow="identity-credentials-get" 屬性附加至 iframe 代碼,如下所示:

  <iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>

如需實際運作情形,請參閱範例

(選用) 如果父框架要限制可呼叫 FedCM 的來源,請傳送 Permissions-Policy 標頭和允許的來源清單。

  Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")

如要進一步瞭解權限政策的運作方式,請參閱「使用權限政策控管瀏覽器功能」。

Login Hint API

RP 可以使用登入提示,建議使用者應登入的帳戶。如果使用者不確定先前使用的帳戶,這項功能有助於重新驗證使用者身分。

RP 可以透過 navigator.credentials.get() 叫用 loginHint 屬性,並使用從帳戶清單端點擷取的其中一個 login_hints 值,選擇性地顯示特定帳戶,如下列程式碼範例所示:

  return await navigator.credentials.get({
    identity: {
      providers: [{
        configURL: 'https://idp.example/manifest.json',
        clientId: '123',
        // Accounts endpoint can specify a 'login_hints' array for an account.
        // When RP specifies a 'exampleHint' value, only those accounts will be
        // shown to the user whose 'login_hints' array contains the 'exampleHint'
        // value
        loginHint : 'exampleHint'
      }]
    }
  });

如果沒有任何帳戶符合 loginHint,FedCM 對話方塊會顯示登入提示,讓使用者登入符合 RP 所要求提示的 IdP 帳戶。使用者輕觸提示時,系統會開啟彈出式視窗,顯示設定檔中指定的登入網址。然後,系統會在連結中附加登入提示和網域提示查詢參數。

網域提示 API

RP 可以選擇只顯示與特定網域相關聯的帳戶。如果 RP 僅限於公司網域,這項功能就非常實用。

如要只顯示特定網域帳戶,RP 應使用從帳戶清單端點擷取的其中一個 domain_hints 值,呼叫 navigator.credentials.get() 函式並設定 domainHint 屬性,如下列程式碼範例所示:

  return await navigator.credentials.get({
    identity: {
      providers: [{
        configURL: 'https://idp.example/manifest.json',
        clientId: 'abc',
        // Accounts endpoint can specify a 'domain_hints' array for an account.
        // When RP specifies a '@domain.example' value, only those accounts will be
        // shown to the user whose 'domain_hints' array contains the
        // '@domain.example' value
        domainHint : '@domain.example'
      }]
    }
  });

如果沒有任何帳戶符合 domainHint,FedCM 對話方塊會顯示登入提示,讓使用者登入符合 RP 所要求提示的 IdP 帳戶。使用者輕觸提示時,系統會開啟彈出式視窗,顯示設定檔中指定的登入網址。然後,系統會在連結中附加登入提示和網域提示查詢參數。

如果沒有任何帳戶符合 domainHint,系統會顯示登入提示,如下圖所示。
如果沒有與 domainHint 相符的帳戶,系統會顯示登入提示範例。

詳情請參閱示範

自訂參數

RP 可透過自訂參數功能,向ID 聲明端點提供額外的鍵/值參數。RP 可以透過 Parameters API 將額外參數傳遞至 IdP,要求基本登入以外的資源權限。在下列情況下,傳遞額外參數會很有幫助:

  • RP 需要動態要求 IdP 擁有的額外權限,例如帳單地址或日曆存取權。使用者可以透過 IdP 控制的 UX 流程授權這些權限,該流程是使用「繼續」功能啟動,然後 IdP 會分享這項資訊。

如要使用 API,RP 會在 navigator.credentials.get() 呼叫中,將參數新增至 params 屬性做為物件:

  let {token} = await navigator.credentials.get({
    identity: {
      providers: [{
        clientId: '1234',
        configURL: 'https://idp.example/fedcm.json',
        // Key/value pairs that need to be passed from the
        // RP to the IdP but that don't really play any role with
        // the browser.
        params: {
          IDP_SPECIFIC_PARAM: '1',
          foo: 'BAR'
        }
      },
    }
  });

瀏覽器會自動將此要求轉換為對 IdP 的 POST 要求,並將參數做為單一網址編碼的 JSON 序列化物件:

  // The assertion endpoint is drawn from the config file
  POST /fedcm_assertion_endpoint HTTP/1.1
  Host: idp.example
  Origin: https://rp.example/
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

  // params are translated into urlencoded version of `{"IDP_SPECIFIC_PARAM":"1","foo":"bar"}`
  account_id=123&client_id=client1234&params=%22%7B%5C%22IDP_SPECIFIC_PARAM%5C%22%3A1%2C%5C%22foo%5C%22%3A%5C%22BAR%5C%22%7D%22.

如果 RP 需要任何額外權限,IdP 可以提供重新導向連結。舉例來說,在 node.js 中:

  if (rpRequestsPermissions) {
    // Response with a URL if the RP requests additional permissions
    return res.json({
      continue_on: '/example-redirect',
    });
  }

欄位

RP 可以指定需要 IdP 分享的使用者資訊 (姓名、電子郵件地址和個人資料相片的任意組合)。系統會在 FedCM 對話方塊的揭露使用者介面中,顯示要求提供的資訊。如果使用者選擇登入,系統會顯示訊息,通知使用者 idp.example 將與 rp.example 分享所要求的資訊。

FedCM 主動模式對話方塊,顯示揭露訊息。如要繼續,身分識別提供者會將使用者的電子郵件地址和個人資料相片提供給網站。
主動模式下的揭露訊息:RP 要求 IdP 只分享使用者電子郵件和個人資料相片。

如要使用「欄位」功能,RP 應在 navigator.credentials.get() 呼叫中新增 fields 陣列。欄位可包含 nameemailpicture 的任何排列組合。日後可能會擴大範圍,納入更多值。 含有 fields 的要求如下所示:

  let { token } = await navigator.credentials.get({
    identity: {
      providers: [{
        // RP requests the IdP to share only user email and profile picture
        fields: [ 'email', 'picture'],
        clientId: '1234',
        configURL: 'https://idp.example/fedcm.json',

      },
    }
  });

瀏覽器會自動將其轉換為對ID 聲明端點的 HTTP 要求,其中包含 RP 指定的 fields 參數,以及瀏覽器在 disclosure_shown_for 參數中向使用者揭露的欄位。為確保向後相容性,如果顯示揭露文字,且要求的欄位包含所有三個欄位'name''email''picture',瀏覽器也會傳送 disclosure_text_shown=true

  POST /id_assertion_endpoint HTTP/1.1
  Host: idp.example
  Origin: https://rp.example/
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

  // The RP only requested to share email and picture. The browser will send `disclosure_text_shown=false`, as the 'name' field value is missing
  account_id=123&client_id=client1234&disclosure_text_shown=false&fields=email,picture&disclosure_shown_for=email,picture

如果 fields 是空陣列,使用者代理程式就會略過揭露資訊的使用者介面。

不會顯示揭露資訊 UI 訊息的 FedCM 被動模式對話方塊。
被動模式不會顯示揭露訊息。在按鈕流程中,系統會完全略過揭露事項使用者介面。

即使帳戶端點的回應不含與 approved_clients 中 RP 相符的用戶端 ID,也是如此。

在本例中,傳送至 ID 聲明端點disclosure_text_shown 在 HTTP 內文中為 false:

  POST /id_assertion_endpoint HTTP/1.1
  Host: idp.example
  Origin: https://rp.example/
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

  account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false

顯示錯誤訊息

有時 IdP 可能會因為正當理由 (例如用戶端未經授權,或伺服器暫時無法使用) 而無法核發權杖。如果 IdP 傳回「錯誤」回應,RP 可以擷取該回應,而 Chrome 則可顯示瀏覽器 UI,並提供 IdP 提供的錯誤資訊,藉此通知使用者。

A
使用者嘗試登入失敗後,FedCM 對話方塊會顯示錯誤訊息。字串與錯誤類型相關聯。
  try {
    const cred = await navigator.credentials.get({
      identity: {
        providers: [
          {
            configURL: 'https://idp.example/manifest.json',
            clientId: '1234',
          },
        ],
      }
    });
  } catch (e) {
    const code = e.code;
    const url = e.url;
  }

在初始驗證後自動重新驗證使用者

FedCM 自動重新驗證 (簡稱「自動重新驗證」) 可讓使用者自動重新驗證。如要自動重新驗證使用者,必須符合下列條件:

  • 使用者先前已使用 FedCM 進行初始驗證。 這裡的「初始驗證」是指使用者在同一個瀏覽器執行個體中,首次輕觸 FedCM 登入對話方塊的「以『<使用者名稱>』身分繼續」按鈕,建立帳戶或登入 RP 網站。
  • 使用者只有一個回訪帳戶。如果多個 IdP 都有回訪帳戶,系統不會自動重新驗證使用者。

在使用者建立聯合帳戶之前,明確的使用者體驗有助於防止追蹤 (這是 FedCM 的主要目標之一),但使用者完成一次後,就不必再經歷這項程序,因為使用者授權允許 RP 和 IdP 之間的通訊後,強制要求使用者再次明確確認先前已確認的內容,對隱私權或安全性沒有任何好處。

使用自動重新驗證時,瀏覽器會根據您在呼叫 navigator.credentials.get() 時為 mediation 指定的選項,變更其行為。

  const cred = await navigator.credentials.get({
    identity: {
      providers: [{
        configURL: 'https://idp.example/fedcm.json',
        clientId: '1234',
      }],
    },
    mediation: 'optional', // this is the default
  });

  // `isAutoSelected` is `true` if auto-reauthn was performed.
  const isAutoSelected = cred.isAutoSelected;

mediationCredential Management API 中的屬性,行為與 PasswordCredentialPasswordCredentialFederatedCredential 相同,且 PublicKeyCredential 也部分支援。這項屬性接受下列四個值:

  • 'optional'(預設):盡可能自動重新驗證,否則需要中介服務。建議在登入頁面選擇這個選項。
  • 'required':一律需要中介服務才能繼續,例如點選 UI 上的「繼續」按鈕。如果使用者每次需要驗證時,都必須明確授予權限,請選擇這個選項。
  • 'silent':盡可能自動重新驗證,如果無法,則以無訊息方式失敗,不需中介服務。建議您在專屬登入頁面以外的頁面選擇這個選項,但仍要讓使用者保持登入狀態,例如運送網站上的項目頁面,或新聞網站上的文章頁面。
  • 'conditional':用於 WebAuthn,目前不適用於 FedCM。

透過這項呼叫,系統會在下列情況下自動重新驗證:

  • FedCM 可供使用。舉例來說,使用者尚未停用 FedCM 全域設定或 RP 設定。
  • 使用者只透過一個帳戶和 FedCM API,登入這個瀏覽器的網站。
  • 使用者已透過該帳戶登入 IdP。
  • 過去 10 分鐘內未自動重新驗證。
  • RP 在上次登入後尚未呼叫 navigator.credentials.preventSilentAccess()

符合這些條件時,系統會在 FedCM navigator.credentials.get() 叫用後,立即嘗試自動重新驗證使用者。

mediation: optional 時,自動重新驗證可能無法使用,原因只有瀏覽器知道;RP 可以檢查 isAutoSelected 屬性,判斷是否執行自動重新驗證。

這有助於評估 API 效能,並據此改善使用者體驗。此外,如果無法使用,系統可能會提示使用者透過明確的使用者中介服務登入,也就是含有 mediation: required 的流程。

使用者透過 FedCM 自動重新驗證。

透過 preventSilentAccess() 強制執行中介服務

使用者登出後立即自動重新驗證,會造成非常糟糕的使用體驗。因此,FedCM 在自動重新驗證後會進入 10 分鐘的靜止期,以防發生這種情況。也就是說,除非使用者在 10 分鐘內重新登入,否則系統最多每 10 分鐘會自動重新驗證一次。當使用者明確登出 RP 時 (例如點選登出按鈕),RP 應呼叫 navigator.credentials.preventSilentAccess(),明確要求瀏覽器停用自動重新驗證。

  function signout() {
    navigator.credentials.preventSilentAccess();
    location.href = '/signout';
  }

使用者可以在設定中選擇停用自動重新驗證功能

使用者可以透過設定選單停用自動重新驗證功能:

  • 在電腦版 Chrome 中,依序前往 chrome://password-manager/settings >「自動登入」。
  • 在 Android 版 Chrome 中,依序開啟「設定」 >「密碼管理工具」 > 輕觸右上角的齒輪圖示 >「自動登入」。

停用切換鈕後,使用者即可完全停用自動重新驗證行為。如果使用者在 Chrome 執行個體中登入 Google 帳戶並啟用同步功能,這項設定就會儲存並同步到所有裝置。

將 IdP 與 RP 中斷連線

如果使用者先前透過 FedCM 使用 IdP 登入 RP,瀏覽器會在本地將這項關係記憶為已連結帳戶清單。RP 可以呼叫 IdentityCredential.disconnect() 函式來啟動中斷連線程序。此函式可從頂層 RP 框架呼叫。RP 必須傳遞 configURL、在 IdP 下使用的 clientId,以及要中斷 IdP 連線的 accountHint。帳戶提示可以是任意字串,只要中斷連線端點可以識別帳戶即可,例如電子郵件地址或使用者 ID,不一定要與帳戶清單端點提供的帳戶 ID 相符:

  // Disconnect an IdP account 'account456' from the RP 'https://idp.com/'. This is invoked on the RP domain.
  IdentityCredential.disconnect({
    configURL: 'https://idp.com/config.json',
    clientId: 'rp123',
    accountHint: 'account456'
  });

IdentityCredential.disconnect() 會傳回 Promise。這個 Promise 可能會因下列原因擲回例外狀況:

  • 使用者尚未透過 FedCM 使用 IdP 登入 RP。
  • 從 iframe 內叫用 API,但沒有 FedCM 權限政策。
  • configURL 無效或缺少中斷連線端點。
  • 內容安全政策 (CSP) 檢查失敗。
  • 有待處理的取消連結要求。
  • 使用者已在瀏覽器設定中停用 FedCM。

IdP 的中斷連線端點傳回回應時,RP 和 IdP 會在瀏覽器上中斷連線,且 Promise 會解析。已取消連結帳戶的 ID 會在取消連結端點的回應中指定。

後續步驟

瞭解如何在識別資訊提供者端,透過 FedCM 實作識別資訊解決方案。
瞭解使用者和開發人員如何管理 FedCM 參與情形,包括在各平台和網站中選擇加入或退出。