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

Chrome 116 推出 FedCM 功能,例如登入提示 API、使用者資訊 API 和 RP Context API,並開始進行 IdP 登入狀態 API 的原始碼試用。

在 Chrome 116 中,Chrome 會推出下列三項新的聯邦憑證管理 (FedCM) 功能:

  • 登入提示 API:指定要登入的偏好使用者帳戶。
  • User Info API:擷取回訪使用者的資訊,讓識別資訊提供者 (IdP) 可以在 iframe 中顯示個人化的登入按鈕。
  • RP Context API:在 FedCM 對話方塊中使用「登入」以外的標題。

此外,Chrome 也開始進行 Origin 試用,以測試 IdP 登入狀態 API。IdP 登入狀態 API 是必要條件,且發布時會造成重大變更。如果您已導入 FedCM,請務必參加來源試用活動。

Login Hint API

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

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

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

這項擴充功能會在 IdP 的帳戶清單端點回應中新增 login_hints 陣列,其中包含 IdP 支援的所有可能篩選器類型。舉例來說,如果 IdP 支援依電子郵件和 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 permissions policy 明確允許。

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

如要查看實際運作情形,請前往 https://fedcm-demo-rp.dev/active-mode

RP Context API

RP Context API 將於 Chrome 116 版推出,可讓 RP 修改 FedCM 對話方塊 UI 中的字串,以配合預先定義的驗證情境。請參閱下列螢幕截圖,瞭解不同選項:

系統會顯示「登入 ****」的 FedCM 對話方塊。
系統會顯示「登入 ****」的 FedCM 對話方塊。如果未指定 RP Context,這是預設選項。
使用
系統會顯示「註冊 ****」的 FedCM 對話方塊
使用 系統會顯示 FedCM 對話方塊,並顯示「繼續前往『****』」
FedCM 對話方塊顯示「使用 ****」
FedCM dialog rendered with "Use ****"

使用方式很簡單,只要提供 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 登入狀態 API 來源試用

Chrome 會從 Chrome 116 開始,在電腦上啟動 IdP 登入狀態 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()

這些事件會將使用者的登入狀態記錄為「登入」。如果使用者的登入狀態設為「登入」,PR 呼叫 FedCM 時會向 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 對話方塊來顯示這些帳戶。
  • 如果端點未傳回任何帳戶,請將狀態更新為「登出」,並讓 FedCM 呼叫失敗。

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

即使 IdP 會持續向瀏覽器回報使用者的登入狀態,但仍可能發生不同步的情況,例如工作階段到期時。當登入狀態為「登入」時,瀏覽器會嘗試將含憑證的要求傳送至帳戶清單端點,但伺服器會拒絕,因為工作階段已失效。在這種情況下,瀏覽器可以透過彈出式視窗,動態讓使用者登入 IdP。

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

FedCM 對話方塊,建議登入 IdP。
系統顯示 FedCM 對話方塊,建議登入 IdP。

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

點選「登入 IdP」按鈕後顯示的彈出式視窗。
按一下「登入 IdP」按鈕後顯示的彈出式視窗。

登入頁面網址 (必須是 IdP 的來源) 可在 IdP 設定檔中指定為 signin_url

{
  "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 的情形。

參加來源試用

如要在本機試用 IdP 登入狀態 API,請在 Chrome 116 以上版本中開啟 Chrome 旗標
chrome://flags#fedcm-idp-signin-status-api

您也可以註冊來源試用兩次,啟用 IdP 登入狀態 API:

您可以透過來源試用程序試用新功能,並向網路標準社群提供意見,協助評估這些功能的實用性、實用性和有效性。詳情請參閱網頁開發人員適用的來源試用指南

IdP Sign-In Status API 來源試用活動從 Chrome 116 開始,到 Chrome 119 結束。

為 IdP 註冊來源試用

  1. 前往原始碼試用版註冊頁面
  2. 按一下「註冊」按鈕並填寫表單,即可要求權杖。
  3. 以「Web Origin」的形式輸入 IdP 的來源。
  4. 按一下「提交」
  5. 在採用 IdentityProvider.close() 的網頁標頭中,加入 origin-trial <meta> 標記。舉例來說,這可能看起來像這樣:
    <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">

為 RP 註冊第三方來源試用

  1. 前往原始碼試用版註冊頁面
  2. 按一下「註冊」按鈕並填寫表單,即可要求權杖。
  3. 以「Web Origin」的形式輸入 IdP 的來源。
  4. 勾選「第三方比對」,即可在其他來源上透過 JavaScript 插入符記。
  5. 按一下「提交」
  6. 在第三方網站上嵌入核發的權杖。

如要在第三方網站中嵌入權杖,請將下列程式碼加入從 IdP 來源放送的 JavaScript 程式庫或 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 網站上