自 Chrome 122 起,Federated Credential Management API (FedCM) 的 Disconnect API 已開放使用。Disconnect API 可讓依賴方在不仰賴第三方 Cookie 的情況下,將使用者與身分提供者的帳戶解除連結。此外,FedCM 的同站處理方式也有一些更新。
Disconnect API
當使用者透過身分聯合功能,在依賴方 (RP,使用身分提供者進行驗證的網站) 上建立帳戶時,身分提供者 (IdP,向其他方提供驗證和帳戶資訊的服務) 通常會在伺服器上記錄連線。儲存的連線可讓 IdP 追蹤使用者登入的 RP,並改善使用者體驗。舉例來說,為了讓使用者日後返回 RP 時獲得更優質的體驗,系統會將透過 IdP 登入的使用者帳戶視為回訪帳戶,並提供自動重新驗證和顯示所用帳戶的個人化按鈕等功能。
有時,IdP 會提供 API,用於將帳戶與 RP 取消連結。不過,斷開連結流程需要進行驗證,並需要 IdP Cookie。在沒有第三方 Cookie 的世界中,當使用者造訪 RP 時,RP 就無法透過瀏覽器 API 與 IdP 中斷連線。由於同一個 IdP 可能會連結多個 IdP 帳戶至特定 RP,因此斷開連結流程需要知道要斷開哪個帳戶。
Disconnect API 可讓使用者透過向指定端點發出信號,將 IdP 帳戶從瀏覽器和 IdP 伺服器上的 RP 中斷連結。使用者必須已透過聯合憑證管理 API (FedCM) 完成身分聯盟程序。使用者一旦遭到中斷連線,下次嘗試使用 IdP 登入 RP 時,系統就會將他們視為新使用者。
將 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
。此承諾可能會因以下原因擲回例外狀況:
- 使用者尚未透過 FedCM 使用 IdP 登入 RP。
- 在沒有 FedCM 權限政策的 iframe 中叫用 API。
- configURL 無效或缺少斷開端點。
- 內容安全政策 (CSP) 檢查失敗。
- 有待處理的斷線要求。
- 使用者已在瀏覽器設定中停用 FedCM。
當 IdP 的斷開連線端點傳回回應時,瀏覽器上的 RP 和 IdP 會中斷連線,且承諾會解析。您可以在解除連結端點的回應中指定要解除連結的使用者帳戶。
設定 IdP 設定檔
為了支援 Disconnect API,IdP 必須支援斷開連線端點,並在其 IdP 設定檔中提供 disconnect_endpoint
屬性及其路徑。
{
"accounts_endpoint": "/accounts",
"id_assertion_endpoint": "/assertion",
...
"disconnect_endpoint: "/disconnect"
}
在取消連結端點取消帳戶連結
透過叫用 IdentityCredential.disconnect()
,瀏覽器會傳送含有 Cookie 和 application/x-www-form-urlencoded
內容類型的跨來源 POST
要求至此斷開連線的端點,並附上以下資訊:
屬性 | 說明 |
---|---|
account_hint |
IdP 帳戶的提示。 |
client_id |
RP 的用戶端 ID。 |
POST /disconnect HTTP/1.1
Host: idp.example
Origin: rp.example
Content-Type: application/x-www-form-urlencoded
Cookie: 0x123
Sec-Fetch-Dest: webidentity
account_hint=account456&client_id=rp123
收到要求後,IdP 伺服器應:
- 使用 CORS (跨來源資源共享) 回應要求。
- 確認要求包含
Sec-Fetch-Dest: webidentity
HTTP 標頭。 - 將
Origin
標頭與client_id
所決定的 RP 來源比對。如果不相符,請拒絕。 - 找出與
account_hint
相符的帳戶。 - 將使用者帳戶從 RP 的已連結帳戶清單中取消連結。
- 以 JSON 格式回應瀏覽器,並附上已識別使用者的
account_id
。
回應 JSON 酬載範例如下所示:
{
"account_id": "account456"
}
如果 IdP 希望瀏覽器改為取消連結與 RP 相關聯的所有帳戶,請傳遞不符合任何帳戶 ID 的字串,例如 "*"
。
當 RP 和 IdP 位於同一網站時,系統現在會略過檢查 /.well-known/web-identity
開發 FedCM 系統時,測試或暫存 RP 伺服器網域可能是實際工作環境 IdP 伺服器的子網域。舉例來說,實際運作 IdP 伺服器位於 idp.example
,而測試 RP 伺服器和測試 IdP 伺服器則位於 staging.idp.example
。不過,由於 well-known 檔案必須放在 IdP 伺服器 eTLD+1 的根目錄中,因此必須放在 idp.example/.well-known/web-identity
中,且為正式版伺服器。由於開發人員在開發期間不一定能將檔案放置在正式環境中,因此無法測試 FedCM。
自 Chrome 122 版起,如果 RP 網域和 IdP 網域相同,Chrome 會略過檢查已知檔案。這樣一來,開發人員就能在這種情境下進行測試。
子資源現在可以設定同網站登入狀態
先前,Chrome 只允許在要求與所有祖系同源時,設定登入狀態 (例如使用 Set-Login: logged-in
標頭)。這可避免透過同網站
fetch()
要求設定登入狀態。
舉例來說,假設有個網站允許使用者在 idp.example
上輸入使用者名稱和密碼,但憑證會透過 fetch()
發布至 login.idp.example
。由於兩個網域是跨來源和相同網站,因此無法使用登入狀態 API 將登入狀態記錄到瀏覽器。
這項異動讓 Login Status API 的同網站要求更加寬鬆,讓上述範例可以使用 HTTP 標頭 (Set-Login:
logged-in
) 設定 login.idp.example
的登入狀態。
摘要
透過使用 Disconnect API,FedCM 現在可以將 RP 與 IdP 斷開連線,而不需要依賴第三方 Cookie。方法是呼叫 RP 上的 IdentityCredential.disconnect()
。透過這項功能,瀏覽器會向 IdP 的斷線端點傳送要求,讓 IdP 終止伺服器和瀏覽器上的連線。
我們已宣布,當 RP 和 IdP 位於同一網站時,系統會為了測試目的略過 /.well-known/web-identity
檢查。此外,現在也可以透過相同網站 IdP 子資源的 HTTP 回應標頭設定登入狀態。