FedCM 更新:IdP Sign-In Status API、Login Hint 等

Chrome 116 提供 FedCM 功能,例如登入提示 API、使用者資訊 API 和 RP 內容 API,並開始進行 IdP 登入狀態 API 的來源試用。

Chrome 116 推出以下三項新的 Federated Credential Management (FedCM) 功能:

  • Login Hint API:指定要登入的首選使用者帳戶。
  • User Info API:擷取回訪使用者的資訊,以便身分識別服務提供者 (IdP) 在 iframe 中顯示個人化的登入按鈕。
  • RP Context API:在 FedCM 對話方塊中使用與「Sign in」不同的標題。

此外,Chrome 也開始為 IdP 登入狀態 API 進行原始版本試驗。IdP Sign-in Status API 是必要條件,且在發布時會是重大變更。如果您已導入 FedCM,請務必參加來源試用。

Login Hint API

叫用 FedCM 時,瀏覽器會顯示指定的 ID 提供者 (IdP) 所提供的已登入帳戶。如果 IdP 支援多個帳戶,系統會列出所有已登入的帳戶。

FedCM 對話方塊顯示多個使用者帳戶。
顯示多個使用者帳戶的 FedCM 對話方塊

使用者登入後,有時依賴方 (RP) 會要求使用者重新驗證。但使用者可能不確定自己使用的是哪個帳戶。如果 RP 可以指定要登入哪個帳戶,使用者就能更輕鬆地選擇帳戶。登入提示已在 Chrome 116 中推出,RP 可藉此將清單縮減為一個。

這個擴充功能會在 IdP 的帳戶清單端點回應中,新增 login_hints 陣列,其中包含 IdP 支援的所有可能篩選器類型。舉例來說,如果 ID 提供者支援依電子郵件和 ID 篩選,帳戶回應可能會像這樣:

{
  "accounts": [{
    "id": "demo1",
    "email": "demo1@example.com",
    "name": "John Doe",
    "login_hints": ["demo1", "demo1@example.com"],
    ...
  }, {
    "id": "demo2",
    "email": "demo2@example.com",
    "name": "Jane Doe",
    "login_hints": ["demo2", "demo2@example.com"],
    ...
  }, ...]
}

在帳戶清單中傳遞 login_hints 後,RP 就能使用 loginHint 屬性叫用 navigator.credentials.get(),如以下程式碼範例所示,以便有選擇性地顯示指定帳戶:

return await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/manifest.json",
      clientId: "123",
      nonce: nonce,
      loginHint : "demo1@example.com"
    }]
  }
});

User Info API

如今,使用者透過身分聯盟登入時,會看到印有 IdP 標誌的登入按鈕。不過,使用使用者的個人資料圖示和資訊裝飾按鈕,可讓使用者更直覺地登入,尤其是當使用者曾透過 IdP 在這個網站上註冊時。

「使用 Google 帳戶登入」按鈕。
使用 Google 帳戶登入按鈕
個人化的「使用 Google 帳戶登入」按鈕。
「使用 Google 帳戶登入」按鈕的個人化設計

挑戰在於,個人化按鈕會依賴 iframe 中 IdP 網域的第三方 Cookie,藉此辨識已登入的使用者並顯示按鈕,因此在第三方 Cookie 淘汰後,這類按鈕就無法使用。

在 Chrome 116 中推出的 User Info API,可讓 IdP 不必仰賴第三方 Cookie,就能從伺服器取得回訪使用者的資訊。

IdP 應從 RP 網站上嵌入的 iframe 中呼叫 API,這樣才能擷取使用者資訊,並顯示個人化按鈕,讓使用者誤以為該按鈕是 RP 途徑的一部分。透過 API 呼叫,瀏覽器會向帳戶清單端點提出要求,然後在下列情況下傳回使用者資訊陣列:

  • 使用者曾在相同的瀏覽器執行個體上,透過 FedCM 與 IdP 登入 RP,且資料尚未清除。
  • 使用者已在相同的瀏覽器例項中登入 IdP。
// Iframe displaying a page from the https://idp.example origin
const user_info = await IdentityProvider.getUserInfo({
    configUrl: "https://idp.example/fedcm.json",
    clientId: "client1234"
});

// IdentityProvider.getUserInfo returns an array of user information.
if (user_info.length > 0) {
  // Chrome puts returning accounts first, so the first account received is guaranteed to be a returning account.
  const name = user_info[0].name;
  const given_name = user_info[0].given_name;
  const display_name = given_name ? given_name : name;
  const picture = user_info[0].picture;
  const email = user_info[0].email;
  // Renders the personalized sign-in button with the information above.
}

請注意,如要允許從與 IdP 相同來源的 iframe 中呼叫 IdentityProvider.getUserInfo(),嵌入的 HTML 必須透過 identity-credentials-get 權限政策明確允許這項操作。

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

您可以在 https://fedcm-rp-demo.glitch.me/button 中查看實際運作情形。

RP Context API

在 Chrome 116 中推出的 RP Context API 可讓 RP 修改 FedCM 對話方塊 UI 中的字串,以便支援預先定義的驗證情境。請參閱下列螢幕截圖,瞭解各種選項:

使用
使用「Sign in to ****」顯示的 FedCM 對話方塊。如果未指定 RP 情境,則會使用這個預設選項。
使用
使用「Sign up to ****」顯示的 FedCM 對話方塊
使用
使用「Continue to ****」顯示的 FedCM 對話方塊
使用
使用「Use ****」顯示的 FedCM 對話方塊

使用方式很簡單,只要提供 identity.context 屬性,其中一個為 "signin" (預設值)、"signup""use""continue"

const credential = await navigator.credentials.get({
  identity: {
    // "signin" is the default, "signup", "use" and "continue" 
    // can also be used
    context: "signup", 
    providers: [{
      configURL: "https://idp.example/fedcm.json",
      clientId: "1234",
    }],
  }
});

IdP Sign-In Status API 來源試用

Chrome 會從 Chrome 116 開始在電腦上啟動 IdP Sign-In Status API 來源試用版,之後再在 Android 版 Chrome 上啟動。來源試用可讓您使用新功能或實驗功能,建立功能,讓使用者在功能正式推出前,先試用一段時間。

IdP 登入狀態 API 是一種機制,可讓 IdP 向瀏覽器告知使用者在 IdP 上的登入狀態。有了這個 API,瀏覽器就能減少對 IdP 的不必要要求,並減輕潛在的時間攻擊。

通知瀏覽器使用者的登入狀態

當使用者在 IdP 上登入,或從所有 IdP 帳戶登出時,IdP 可以透過傳送 HTTP 標頭或呼叫 JavaScript API,向瀏覽器傳送使用者的登入狀態。瀏覽器會將狀態記錄為下列其中一種狀態:「sign-in」、「sign-out」或「unknown」(預設值)。

如要指出使用者已登入,請在頂層導覽或相同來源子資源要求中傳送 IdP-SignIn-Status: action=signin HTTP 標頭:

IdP-SignIn-Status: action=signin

或者,您也可以從 IdP 來源呼叫 JavaScript API IdentityProvider.login()

IdentityProvider.login()

這些事件會將使用者的登入狀態記錄為「登入」。當使用者的登入狀態設為「登入」時,呼叫 FedCM 的 PR 會向 IdP 的帳戶清單端點提出要求,並在 FedCM 對話方塊中向使用者顯示可用的帳戶。

如要傳達使用者已登出所有帳戶,請在頂層導覽或相同來源子資源要求中傳送 IdP-SignIn-Status: action=signout-all HTTP 標頭:

IdP-SignIn-Status: action=signout-all

或者,您也可以從 IdP 來源呼叫 JavaScript API IdentityProvider.logout()

IdentityProvider.logout()

這些事件會將使用者的登入狀態記錄為「登出」。當使用者的登入狀態為「登出」時,呼叫 FedCM 會在沒有向 IdP 帳戶清單端點提出要求的情況下,以靜默方式失敗。

根據預設,IDP 登入狀態會設為「unknown」。這個狀態會在 IdP 使用 IdP 登入狀態 API 傳送信號之前使用。我們引入這個狀態,是為了提供更佳的轉換效果。因為在我們發布這個 API 時,使用者可能已登入 IdP,而 IdP 可能無法在首次叫用 FedCM 時向瀏覽器傳送這項信號。在這種情況下,我們會向 IdP 的帳戶清單端點提出要求,並根據帳戶清單端點的回應更新狀態:

  • 如果端點傳回有效帳戶清單,請將狀態更新為「登入」,然後開啟 FedCM 對話方塊,顯示這些帳戶。
  • 如果端點未傳回任何帳戶,請將狀態更新為「sign-out」,並讓 FedCM 呼叫失敗。

如果使用者工作階段到期,該怎麼辦?讓使用者透過動態登入流程登入

即使 IdP 會持續向瀏覽器通知使用者的登入狀態,但在工作階段到期時,兩者可能會不同步。當登入狀態為「登入」時,瀏覽器會嘗試將具備憑證的要求傳送至帳戶清單端點,但由於工作階段已無法使用,因此伺服器會拒絕要求。在這種情況下,瀏覽器可以透過彈出式視窗,讓使用者動態登入 IdP。

FedCM 對話方塊會顯示訊息,如下圖所示:

FedCM 對話方塊建議登入 IdP。
FedCM 對話方塊建議登入 IdP。

點選「Continue」按鈕後,瀏覽器會開啟彈出式視窗,將使用者導向 IdP 的登入頁面。

點選「Sign in to the IdP」按鈕後顯示的彈出式視窗。
點選「登入 IdP」按鈕後顯示的彈出式視窗。

您可以使用 signin_url 指定登入頁面網址 (必須是 IdP 的來源),做為 IdP 設定檔的一部分。

{
  "accounts_endpoint": "/auth/accounts",
  "client_metadata_endpoint": "/auth/metadata",
  "id_assertion_endpoint": "/auth/idtokens",
  "signin_url": "/signin"
  }
}

彈出式視窗是使用第一方 Cookie 的一般瀏覽器視窗。內容視窗中的任何事件都由 IdP 負責,但沒有可用於向 RP 頁面提出跨來源通訊要求的視窗句柄。使用者登入後,IdP 應:

  • 傳送 IdP-SignIn-Status: action=signin 標頭或呼叫 IdentityProvider.login() API,通知瀏覽器使用者已登入。
  • 呼叫 IdentityProvider.close() 即可關閉自身 (彈出式視窗)。
// User is signed in...
// Don't forget feature detection.
if (IdentityProvider) {
  // Signal to the browser that the user has signed in.
  IdentityProvider.close();
}
使用者使用 FedCM 登入 IdP 後,登入 RP

您可以在我們的示範中試用 IdP 登入狀態 API 行為。您登入示範 IdP 後,工作階段會在三分鐘後過期。接著,您可以透過彈出式視窗行為觀察 IdP 的登入作業。

參與來源試用

您可以在 Chrome 116 以上版本中開啟Chrome 旗標 chrome://flags#fedcm-idp-signin-status-api
在本機測試 IdP 登入狀態 API。

您也可以註冊兩次來源試用來啟用 IdP Sign-In Status API:

來源試用計畫可讓您試用新功能,並針對其可用性、實用性和有效性向網頁標準社群提供意見回饋。詳情請參閱網頁開發人員的來源試用指南

IdP Sign-In Status API 來源試用從 Chrome 116 到 Chrome 119 開放使用。

為 IdP 註冊來源試用

  1. 前往原始試用註冊頁面
  2. 按一下「註冊」按鈕,然後填寫表單,即可索取權杖。
  3. 將 ID 提供者的來源輸入為「網站來源」
  4. 按一下「提交」
  5. 在使用 IdentityProvider.close() 的網頁標頭中加入 origin-trial <meta> 標記。例如:
    <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">

為 RP 註冊第三方來源試用

  1. 前往原始試用註冊頁面
  2. 按一下「註冊」按鈕,然後填寫表單,即可索取權杖。
  3. 將 ID 提供者的來源輸入為「網站來源」
  4. 勾選「第三方比對」,即可在其他來源中使用 JavaScript 插入符記。
  5. 按一下「提交」
  6. 在第三方網站上嵌入已核發的權杖。

如要在第三方網站上嵌入權杖,請將下列程式碼加入 JavaScript 程式庫或從 IdP 來源提供的 SDK。

const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);

TOKEN_GOES_HERE 替換為您自己的符記。

互動及分享意見回饋

如果您在測試期間有任何意見或遇到問題,可以前往 crbug.com 分享。

相片來源:Dan Cristian PădurețUnsplash 網站上提供