允許透過相關來源要求,在網站上重複使用密碼金鑰

Maud Nalpas
Maud Nalpas

密碼金鑰會連結至特定網站,只能用於登入建立時所屬的網站。

這是由憑證方 ID (RP ID) 指定,針對 example.com 網域建立的密碼金鑰可能是 www.example.comexample.com

雖然 RP ID 可防止密碼金鑰做為單一憑證,用於在任何地方進行驗證,但會造成下列問題:

  • 有多個網域的網站:使用者無法使用同一組密碼金鑰,登入同一間公司管理的不同國家/地區專屬網域 (例如 example.comexample.co.uk)。
  • 品牌網域:使用者無法在單一品牌使用的不同網域 (例如 acme.comacmerewards.com) 中使用相同憑證。
  • 行動應用程式:行動應用程式通常沒有自己的網域,因此難以管理憑證。

您可以透過身分聯盟或 iframe 解決問題,但有時會很不方便。相關來源要求提供解決方案。

解決方案

網站可透過「相關來源要求」指定允許使用其 RP ID 的來源。

這樣一來,使用者就能在您經營的多個網站上重複使用同一組密碼金鑰。

如要使用相關來源要求,您需要在特定網址 https://{RP ID}/.well-known/webauthn 提供特殊 JSON 檔案。如果 example.com 想要允許其他來源將其做為 RP ID 使用,則應在 https://example.com/.well-known/webauthn: 提供下列檔案:

{
  "origins": [
    "https://example.co.uk",
    "https://example.de",
    "https://example-rewards.com"
  ]
}

下次這些網站呼叫密碼金鑰建立 (navigator.credentials.create) 或驗證 (navigator.credentials.get) 時,如果使用 example.com 做為 RP ID,瀏覽器會發現 RP ID 與要求來源不符。如果瀏覽器支援相關來源要求,系統會先在 https://{RP ID}/.well-known/webauthn 尋找 webauthn 檔案。如果檔案存在,瀏覽器會檢查發出要求的來源是否位於 allowlist。如果是,系統會繼續執行密碼金鑰建立或驗證步驟。

如果瀏覽器不支援相關來源要求,就會擲回 SecurityError

瀏覽器支援

Browser Support

  • Chrome: 133.
  • Edge: 133.
  • Firefox: 135.
  • Safari: 17.4.

Source

下列示範使用兩個網站:https://ror-1.glitch.mehttps://ror-2.glitch.me。如要讓使用者在兩個網站上使用同一個密碼金鑰登入,系統會使用相關來源要求,允許 ror-2.glitch.meror-1.glitch.me 做為 RP ID。

示範

https://ror-2.glitch.me 會實作相關來源要求,將 ror-1.glitch.me 做為 RP ID,因此 ror-1ror-2 在建立或驗證密碼金鑰時,都會使用 ror-1.glitch.me 做為 RP ID。 我們也在這些網站導入共用密碼金鑰資料庫。

請注意下列使用者體驗:

  • 您可以在「ror-2」上成功建立密碼金鑰並進行驗證,即使其 RP ID 為「ror-1」(而非「ror-2」)。
  • ror-1ror-2 上建立密碼金鑰後,您就能在 ror-1ror-2 上使用該密碼金鑰進行驗證。由於 ror-2ror-1 指定為 RP ID,因此從上述任一網站提出密碼金鑰建立或驗證要求,都等同於在 ror-1 提出要求。RP ID 是將要求繫結至來源的唯一項目。
  • ror-1ror-2 建立密碼金鑰後,Chrome 就能在 ror-1ror-2 自動填入密碼金鑰。
  • 在上述任一網站建立的憑證,其 RP ID 為 ror-1
Chrome 會自動填入兩個網站的資訊。
有了相關來源要求,使用者就能在 ror-1 和 ror-2 中使用相同的密碼金鑰憑證。Chrome 也會自動填入憑證。

查看程式碼:

步驟 1:導入共用帳戶資料庫

如要讓使用者在 site-1site-2 都能使用同一組密碼金鑰登入,請實作這兩個網站共用的帳戶資料庫。

步驟 2:在 site-1 中設定 .well-known/webauthn JSON 檔案

首先,請設定 site-1.com,允許 site-2.com 將其做為 RP ID。如要這麼做,請建立 WebAuthn JSON 檔案:

{
    "origins": [
        "https://site-2.com"
    ]
}

JSON 物件必須包含名為 origins 的鍵,其值為一或多個包含網頁來源的字串陣列。

重要限制:最多 5 個標籤

系統會處理這份清單中的每個元素,以擷取 eTLD + 1 標籤。 舉例來說,example.co.ukexample.de 的 eTLD + 1 標籤都是 example。但 example-rewards.com 的 eTLD + 1 標籤是 example-rewards。 在 Chrome 中,標籤數量上限為 5 個。

步驟 3:在 site-1 中提供 .well-known/webauthn JSON

然後在 site-1.com/.well-known/webauthn 下提供 JSON 檔案。

舉例來說,在 Express 中:

app.get("/.well-known/webauthn", (req, res) => {
  const origins = {
    origins: ["https://site-2.com"],
  };
  return res.json(origins);
});

這裡我們使用 express res.json,這已設定正確的 content-type ('application/json');

步驟 4:在 site-2 中指定 RP ID

site-2 程式碼集中,視需要將 site-1.com 設為 RP ID:

  • 建立憑證後:
    • 在傳遞至 navigator.credentials.create 前端呼叫的憑證建立 options 中,將 site-1.com 設為 RP ID,通常是在伺服器端產生。options
    • 在將憑證儲存至資料庫前,請先執行憑證驗證,並將 site-1.com 設為預期的 RP ID。
  • 驗證完成後:
    • 在傳遞至 navigator.credentials.get 前端呼叫的驗證 options 中,將 site-1.com 設為 RP ID,且通常是在伺服器端產生。site-1.com
    • site-1.com 設為伺服器上要驗證的預期 RP ID,因為您會在驗證使用者身分前執行憑證驗證。

疑難排解

Chrome 中顯示錯誤訊息彈出式視窗。
在 Chrome 中建立憑證時顯示的錯誤訊息。如果系統在 `https://{RP ID}/.well-known/webauthn` 找不到 `.well-known/webauthn` 檔案,就會擲回這項錯誤。
Chrome 中顯示錯誤訊息彈出式視窗。
在 Chrome 中建立憑證時顯示的錯誤訊息。如果系統找到 `.well-known/webauthn` 檔案,但檔案未列出您嘗試建立憑證的來源,就會擲回這項錯誤。

其他注意事項

在網站和行動應用程式之間共用密碼金鑰

相關來源要求可讓使用者在多個網站重複使用密碼金鑰。如要讓使用者在網站行動應用程式中重複使用密碼金鑰,請採用下列技巧:

在多個網站之間共用密碼

相關來源要求可讓使用者在不同網站重複使用密碼金鑰。 各個密碼管理工具分享網站密碼的方式不盡相同。 如果是 Google 密碼管理工具,請使用 Digital Asset Links 。 Safari 採用不同系統

憑證管理工具和使用者代理程式的角色

這已超出網站開發人員的範疇,但請注意,從長遠來看,RP ID 不應是使用者代理程式或使用者使用的憑證管理工具中,使用者可見的概念。使用者代理程式和憑證管理工具應向使用者顯示憑證的使用位置。這項變更需要時間才能完成。暫時的解決方法是同時顯示目前的網站和原始註冊網站。