Chrome 120 會為 FedCM 提供登入狀態 API。登入狀態 API (舊稱 IdP 登入狀態 API) 可讓網站 (尤其是身分識別資訊提供者) 在使用者登入或登出時,向瀏覽器傳送信號。FedCM 會使用這項信號來解決無聲時間攻擊問題,讓 FedCM 完全不使用第三方 Cookie。這項更新會處理我們先前在FedCM 原始出貨意圖中指出的最後幾項向後不相容的變更,這也是我們工作範圍的一部分。
雖然 Login Status API 可改善隱私權屬性和可用性,但一旦發布,就會造成向後不相容的變更。如果您已實作 FedCM,請務必按照下列操作說明進行更新。
此外,Chrome 也推出了兩項新的 Federated Credential Management (FedCM) 功能:
- 錯誤 API:在使用者登入失敗時,根據 ID 斷言端點 (如有) 的伺服器回應,使用原生 UI 通知使用者。
- Auto-Selected Flag API:如果在流程中自動選取憑證,通知身分識別資訊提供者 (IdP) 和信賴方 (RP)。
Login Status API
登入狀態 API 是一種機制,可讓網站 (尤其是 IdP) 向瀏覽器告知使用者在 IdP 上的登入狀態。有了這個 API,瀏覽器就能減少對 IdP 的不必要要求,並減輕潛在的時間攻擊。
通知瀏覽器使用者的登入狀態
當使用者登入 IdP 或登出所有 IdP 帳戶時,IdP 可以透過傳送 HTTP 標頭或呼叫 JavaScript API,向瀏覽器傳送使用者的登入狀態。對於每個 IdP (以其設定網址識別),瀏覽器會保留一個三態變數,代表登入狀態,可能的值為 logged-in
、logged-out
和 unknown
。預設狀態為 unknown
。
如要指出使用者已登入,請在頂層導覽或相同來源子資源要求中傳送 Set-Login: logged-in
HTTP 標頭:
Set-Login: logged-in
或者,您也可以從 IdP 來源呼叫 JavaScript API navigator.login.setStatus('logged-in')
:
navigator.login.setStatus('logged-in');
這些呼叫會將使用者的登入狀態記錄為 logged-in
。當使用者的登入狀態設為 logged-in
時,呼叫 FedCM 的 RP 會向 IdP 的帳戶清單端點提出要求,並在 FedCM 對話方塊中向使用者顯示可用的帳戶。
如要指出使用者已登出所有帳戶,請在頂層導覽或相同來源子資源要求中傳送 Set-Login:
logged-out
HTTP 標頭:
Set-Login: logged-out
或者,您也可以從 IdP 來源呼叫 JavaScript API navigator.login.setStatus('logged-out')
:
navigator.login.setStatus('logged-out');
這些呼叫會將使用者的登入狀態記錄為 logged-out
。如果使用者的登入狀態為 logged-out
,呼叫 FedCM 會在未向 IdP 的帳戶清單端點提出要求的情況下,以靜默方式失敗。
unknown
狀態會在 IdP 使用 Login Status API 傳送信號之前設定。我們推出這個狀態是為了提供更順暢的轉換體驗,因為在我們發布這個 API 時,使用者可能已登入 IdP。在首次叫用 FedCM 時,IdP 可能沒有機會向瀏覽器傳送這項信號。在這種情況下,我們會向 IdP 的帳戶清單端點提出要求,並根據帳戶清單端點的回應更新狀態:
- 如果端點傳回的清單中含有有效帳戶,請將狀態更新為
logged-in
,並開啟 FedCM 對話方塊來顯示這些帳戶。 - 如果端點未傳回任何帳戶,請將狀態更新為
logged-out
,並讓 FedCM 呼叫失敗。
如果使用者工作階段到期,該怎麼辦?讓使用者透過動態登入流程登入!
即使 IdP 會持續向瀏覽器通知使用者的登入狀態,但狀態可能會不同步,例如在工作階段到期時。當登入狀態為 logged-in
時,瀏覽器會嘗試將憑證要求傳送至帳戶清單端點,但由於工作階段已無法使用,因此伺服器不會傳回任何帳戶。在這種情況下,瀏覽器可以透過對話方塊,讓使用者動態登入 IdP。
FedCM 對話方塊會顯示訊息,建議您登入,如下圖所示。

使用者點選「Continue」按鈕後,瀏覽器會開啟 IdP 登入頁面的對話方塊。

您可以使用 login_url
指定登入頁面網址,做為IdP 設定檔案的一部分。
{
"accounts_endpoint": "/auth/accounts",
"client_metadata_endpoint": "/auth/metadata",
"id_assertion_endpoint": "/auth/idtokens",
"login_url": "/login"
}
}
對話方塊是含有第一方 Cookie 的一般瀏覽器視窗。對話方塊中的所有事件都由 IdP 處理,而且沒有可用於向 RP 頁面提出跨來源通訊要求的視窗句柄。使用者登入後,IdP 應:
- 傳送
Set-Login: logged-in
標頭或呼叫navigator.login.setStatus("logged-in")
API,通知瀏覽器使用者已登入。 - 呼叫
IdentityProvider.close()
即可關閉對話方塊。

您可以在我們的示範中試用 Login Status API 行為。
- 輕觸「前往 IdP 並登入」按鈕。
- 使用任意帳戶登入。
- 從「Account Status」下拉式選單中選取「Session Expired」。
- 按下「更新個人資訊」按鈕。
- 輕觸「前往 RP 試用 FedCM」按鈕。
您應該可以透過模組行為觀察到登入 IdP 的情形。
Error API
當 Chrome 向 ID 斷言端點傳送要求 (例如使用者按下 FedCM UI 上的「Continue as」按鈕或觸發自動重新驗證時),IdP 可能無法基於合法理由發出權杖。例如,如果用戶端未經授權、伺服器暫時無法使用等等。目前,Chrome 會在發生此類錯誤時,自動拒絕要求,並只透過拒絕承諾來通知 RP。
透過 Error API,Chrome 會顯示原生 UI,並顯示 IdP 提供的錯誤資訊,以便通知使用者。

IdP HTTP API
在 id_assertion_endpoint
回應中,如果可依要求核發,IdP 可以將權杖傳回瀏覽器。在這個提案中,如果無法發出權杖,IdP 可以傳回「error」回應,其中包含兩個新的選用欄位:
code
url
// id_assertion_endpoint response
{
"error": {
"code": "access_denied",
"url": "https://idp.example/error?type=access_denied"
}
}
在程式碼方面,IdP 可以從 OAuth 2.0 指定的錯誤清單 (invalid_request
、unauthorized_client
、access_denied
、server_error
和 temporarily_unavailable
) 中選擇其中一個已知錯誤,或使用任意字串。如果是後者,Chrome 會顯示含有一般錯誤訊息的錯誤 UI,並將代碼傳遞至 RP。
對於 url
,它會找出可供人類閱讀的網頁,並提供錯誤相關資訊,向使用者提供錯誤的其他資訊。這個欄位對使用者來說很實用,因為瀏覽器無法在原生 UI 中提供豐富的錯誤訊息。例如後續步驟的連結、客戶服務聯絡資訊等。如果使用者想進一步瞭解錯誤詳細資料和修正方式,可以透過瀏覽器 UI 造訪提供的頁面,這個網址必須與 IdP configURL
位於相同網站。
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;
}
Auto-Selected Flag API
mediation: optional
是 Credential Management API 中的預設使用者中介行為,並會盡可能觸發自動重新驗證。不過,自動重新驗證可能會因瀏覽器無法取得的原因而無法使用;在無法使用時,系統可能會提示使用者透過明確的使用者中介服務登入,這是一個具有不同屬性的流程。
- 從 API 呼叫端的角度來看,當他們收到 ID 權杖時,無法得知該權杖是否是自動重新驗證流程的結果。這會讓他們難以評估 API 效能,並據此改善使用者體驗。
- 從 IdP 的角度來看,他們也無法判斷自動重新驗證是否發生,以便評估成效。此外,明確的使用者中介是否涉及,也能協助他們支援更多安全性相關功能。舉例來說,有些使用者可能偏好更高的安全層級,這類層級需要在驗證時明確介入使用者。如果 IdP 收到的權杖要求未經過此類中介,則可能會以不同的方式處理要求。例如,傳回錯誤代碼,讓 RP 可以再次使用
mediation: required
呼叫 FedCM API。
因此,提供自動重新驗證流程的瀏覽權限對開發人員有益。
透過自動選取的 Flag API,Chrome 會在發生自動重新驗證或明確中介服務時,與 IdP 和 RP 分享是否透過輕觸「Continue as」按鈕取得明確的使用者權限。只有在使用者授予 IdP/RP 通訊權限後,才會進行分享。
IdP 共用
如要將資訊分享給 IdP 後,Chrome 會在傳送至 id_assertion_endpoint
的 POST
要求中加入 is_auto_selected=true
:
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
account_id=123&client_id=client1234&nonce=Ct0D&disclosure_text_shown=true&is_auto_selected=true
共用 RP
瀏覽器可以透過 IdentityCredential
將資訊分享至 isAutoSelected
中的 RP:
const cred = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/manifest.json',
clientId: '1234'
}]
}
});
if (cred.isAutoSelected !== undefined) {
const isAutoSelected = cred.isAutoSelected;
}
互動及分享意見回饋
如有任何意見或在測試期間遇到問題,請前往 crbug.com 分享。
相片來源:Girl with red hat 在 Unsplash 上