相關網站集:開發人員指南

相關網站集合 (RWS) 是一種網路平台機制,可協助瀏覽器瞭解多個網域之間的關係。這樣一來,瀏覽器就能做出關鍵決策,啟用特定網站功能 (例如是否允許存取跨網站 Cookie),並將這項資訊呈現給使用者。

Chrome 淘汰第三方 Cookie 的目標,是為了維持網頁上的重要用途,同時提升使用者隱私權。舉例來說,許多網站都會使用多個網域,提供單一使用者體驗。機構可能會想為多種用途維護不同的頂層網域,例如特定國家/地區的網域,或是用於代管圖片或影片的服務網域。相關網站集可讓網站透過特定控制項,在不同網域之間共用資料。

概括來說,相關網站集是網域的集合,其中包含一個「set primary」和可能的多個「set member」。

在以下範例中,primary 會列出主要網域,而 associatedSites 會列出符合相關子集要求的網域。

{
  "primary": "https://primary.com",
  "associatedSites": ["https://associate1.com", "https://associate2.com", "https://associate3.com"]
}

標準的相關網站組清單是公開可檢視的清單,採用 JSON 檔案格式,並託管在 相關網站組 GitHub 存放區中,可做為所有組的真實來源。Chrome 會使用這個檔案,套用至其行為。

只有擁有網域管理員權限的使用者,才能建立該網域的集合。提交者必須宣告每個「set member」與其「set primary」之間的關係。集合成員可包含多種不同網域類型,且必須根據用途建立子集

如果您的應用程式需要存取同一組相關網站中的跨網站 Cookie (也稱為第三方 Cookie),您可以使用 Storage Access API (SAA)requestStorageAccessFor API 來要求存取這些 Cookie。視各個網站所屬的子集而定,瀏覽器可能會以不同方式處理要求。

如要進一步瞭解提交套裝組合的程序和相關規定,請參閱提交指南。提交的組合會經過各種技術檢查,以驗證提交內容。

如果機構需要在不同頂層網站之間共用身分,相關網站集就是最佳選擇。

相關網站集合的部分用途包括:

  • 自訂國家/地區。使用本地化網站,同時仰賴共用基礎架構 (example.co.uk 可能會仰賴由 example.ca 代管的服務)。
  • 服務網域整合。使用使用者從未直接互動的服務網域,但在同一機構的網站上提供服務 (example-cdn.com)。
  • 使用者內容分離。出於安全考量,將使用者上傳的內容與其他網站內容分開,並允許沙箱網域存取驗證 (和其他) Cookie。如果您要提供不活躍的使用者上傳內容,也可以按照最佳做法,在同一網域中安全地代管內容。
  • 嵌入的已驗證內容。支援來自不同關聯資源的嵌入內容 (影片、文件或資源,僅限於已在頂層網站登入的使用者)。
  • 登入:支援在相關聯的資源中登入。FedCM API 也可能適合用於某些用途。
  • Analytics。在相關資源中部署分析和評估使用者歷程,以改善服務品質。

儲存空間存取權 API

Browser Support

  • Chrome: 119.
  • Edge: 85.
  • Firefox: 65.
  • Safari: 11.1.

Source

Storage Access API (SAA) 可讓嵌入的跨來源內容存取儲存空間,而這類內容通常只能在第一方情境中存取。

嵌入式資源可以使用 SAA 方法,檢查目前是否有存取儲存空間的權限,並向使用者代理程式要求存取權。

當第三方 Cookie 遭到封鎖,但相關網站組合 (RWS) 已啟用時,Chrome 會在 RWS 內部內容中自動授予權限,否則會向使用者顯示提示。(「RWS 內部內容」是指嵌入網站和頂層網站位於同一 RWS 的 iframe 等內容)。

檢查並要求儲存空間存取權

如要檢查目前是否有存取儲存空間的權限,嵌入式網站可以使用 Document.hasStorageAccess() 方法。

這個方法會傳回承諾,並以布林值解析,指出文件是否已存取其 Cookie。如果 iframe 與頂層框架具有相同的來源,則承諾也會傳回 true。

如要在跨網站內容中要求存取 Cookie,嵌入網站可以使用 Document.requestStorageAccess() (rSA)。

requestStorageAccess() API 應從 iframe 內呼叫。該 iframe 必須剛剛收到使用者互動 (所有瀏覽器都需要的 使用者手勢),但 Chrome 還要求使用者在過去 30 天內曾造訪擁有該 iframe 的網站,並以頂層文件 (而非 iframe) 的形式與該網站互動。

requestStorageAccess() 會傳回承諾,用於解析是否已授予儲存空間存取權。如果存取權因任何原因遭到拒絕,系統會拒絕承諾並附上原因。

在 Chrome 中使用 requestStorageAccessFor

Browser Support

  • Chrome: 119.
  • Edge: 119.
  • Firefox: not supported.
  • Safari: not supported.

Source

Storage Access API 只允許已嵌入的網站在收到使用者互動的 <iframe> 元素中,要求存取儲存空間。

這會導致採用 Storage Access API 的頂層網站遇到挑戰,因為這些網站使用跨網站圖片或需要 Cookie 的腳本代碼。

為解決這個問題,Chrome 已實作一種方式,讓頂層網站可透過 Document.requestStorageAccessFor() (rSAFor) 代表特定來源要求存取儲存空間。

 document.requestStorageAccessFor('https://target.site')

requestStorageAccessFor() API 應由頂層文件呼叫。該文件也必須剛剛收到使用者互動。不過,與 requestStorageAccess() 不同的是,Chrome 不會檢查過去 30 天內頂層文件中的互動情形,因為使用者已在該頁面中。

檢查儲存空間存取權限

使用者授予的權限會決定是否允許存取某些瀏覽器功能,例如相機或地理位置。Permissions API 可讓您檢查存取 API 的權限狀態,包括權限是否已授予、拒絕,或需要使用者進行某種互動,例如點選提示或與頁面互動。

您可以使用 navigator.permissions.query() 查詢權限狀態。

如要檢查目前情境的儲存空間存取權限,您必須傳入 'storage-access' 字串:

navigator.permissions.query({name: 'storage-access'})

如要檢查指定來源的儲存空間存取權限,您必須傳入 'top-level-storage-access' 字串:

navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'})

請注意,為保護嵌入來源的完整性,這項檢查只會使用 document.requestStorageAccessFor 檢查頂層文件授予的權限。

系統會根據權限是否可自動授予,或是否需要使用者手勢,傳回 promptgranted

每影格模型

rSA 授權適用於每個影格。rSA 和 rSAFor 授權會視為不同的權限。

每個新畫面都必須個別要求儲存空間存取權,系統會自動授予存取權。只有第一個要求需要使用者手勢,iframe 啟動的任何後續要求 (例如導覽或子資源) 都不需要等待使用者手勢,因為初始要求會為瀏覽工作階段授予手勢。

重新整理、重新載入或以其他方式重新建立 iframe 時,都必須再次要求存取權。

Cookie 必須同時指定 SameSite=NoneSecure 屬性,因為 rSA 只會提供已標示用於跨網站情境的 Cookie 存取權

含有 SameSite=LaxSameSite=Strict 或未含 SameSite 屬性的 Cookie 僅供第一方使用,無論是否使用 rSA,都絕不會在跨網站結構定義中分享。

安全性

針對 rSAFor,子資源要求需要跨來源資源共享 (CORS) 標頭或資源上的 crossorigin 屬性,確保明確選擇加入。

導入範例

從嵌入的跨來源 iframe 要求存取儲存空間

圖表:顯示頂層.site 上的內嵌網站
在其他網站的嵌入內容中使用 requestStorageAccess()

檢查是否具備儲存空間存取權

如要確認是否已具備儲存空間存取權,請使用 document.hasStorageAccess()

如果承諾解析為 true,您就可以在跨網站情境中存取儲存空間。如果解析結果為 false,您就需要要求儲存空間存取權。

document.hasStorageAccess().then((hasAccess) => {
    if (hasAccess) {
      // You can access storage in this context
    } else {
      // You have to request storage access
    }
});

要求儲存空間存取權

如果您需要要求儲存空間存取權,請先檢查儲存空間存取權 navigator.permissions.query({name: 'storage-access'}),瞭解是否需要使用者手勢,或是可以自動授予。

如果權限為 granted,您可以呼叫 document.requestStorageAccess(),且不必透過使用者手勢就能成功。

如果權限狀態為 prompt,您必須在使用者手勢 (例如按一下按鈕) 後發出 document.requestStorageAccess() 呼叫。

範例:

navigator.permissions.query({name: 'storage-access'}).then(res => {
  if (res.state === 'granted') {
    // Permission has already been granted
    // You can request storage access without any user gesture
    rSA();
  } else if (res.state === 'prompt') {
    // Requesting storage access requires user gesture
    // For example, clicking a button
    const btn = document.createElement("button");
    btn.textContent = "Grant access";
    btn.addEventListener('click', () => {
      // Request storage access
      rSA();
    });
    document.body.appendChild(btn);
  }
});

function rSA() {
  if ('requestStorageAccess' in document) {
    document.requestStorageAccess().then(
      (res) => {
        // Use storage access
      },
      (err) => {
        // Handle errors
      }
    );
  }
}

後續從框架、導覽或子資源發出的要求,將自動取得存取跨網站 Cookie 的權限。hasStorageAccess() 會傳回 true,且同一個相關網站組的跨網站 Cookie 會在這些要求中傳送,而不需要任何額外的 JavaScript 呼叫。

圖表顯示 requestStorageAccessFor() 是在頂層網站上使用,而非在嵌入內容中
在頂層網站上使用 requestStorageAccessFor() 來處理其他來源

頂層網站可以使用 requestStorageAccessFor(),代表特定來源要求儲存空間存取權。

hasStorageAccess() 只會檢查呼叫它的網站是否具有儲存空間存取權,因此頂層網站可以檢查其他來源的權限。

如要瞭解系統是否會向使用者顯示提示訊息,或是否已將儲存空間存取權授予指定來源,請呼叫 navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'})

如果權限為 granted,您可以呼叫 document.requestStorageAccessFor('https://target.site')。無需使用者手勢也應能成功。

如果權限為 prompt,您就需要在使用者手勢 (例如按一下按鈕) 後方鉤住 document.requestStorageAccessFor('https://target.site') 呼叫。

範例:

navigator.permissions.query({name:'top-level-storage-access',requestedOrigin: 'https://target.site'}).then(res => {
  if (res.state === 'granted') {
    // Permission has already been granted
    // You can request storage access without any user gesture
    rSAFor();
  } else if (res.state === 'prompt') {
    // Requesting storage access requires user gesture
    // For example, clicking a button
    const btn = document.createElement("button");
    btn.textContent = "Grant access";
    btn.addEventListener('click', () => {
      // Request storage access
      rSAFor();
    });
    document.body.appendChild(btn);
  }
});

function rSAFor() {
  if ('requestStorageAccessFor' in document) {
    document.requestStorageAccessFor().then(
      (res) => {
        // Use storage access
      },
      (err) => {
        // Handle errors
      }
    );
  }
}

requestStorageAccessFor() 呼叫成功後,如果跨網站要求包含 CORS 或 crossorigin 屬性,就會納入 Cookie,因此網站可能會在觸發要求前等待一會兒。

要求必須使用 credentials: 'include' 選項,資源則必須包含 crossorigin="use-credentials" 屬性。

function checkCookie() {
    fetch('https://related-website-sets.glitch.me/getcookies.json', {
        method: 'GET',
        credentials: 'include'
      })
      .then((response) => response.json())
      .then((json) => {
      // Do something
      });
  }

如何在本機測試

必要條件

如要在本機測試相關網站組合,請使用透過命令列啟動的 Chrome 119 以上版本,並啟用 test-third-party-cookie-phaseout Chrome 標記

啟用 Chrome 標記

如要啟用必要的 Chrome 旗標,請在網址列中前往 chrome://flags#test-third-party-cookie-phaseout,然後將旗標變更為 Enabled。變更標記後,請務必重新啟動瀏覽器。

如要啟動含有本機宣告的相關網站集合的 Chrome,請建立 JSON 物件,其中包含一組網址的網址,並將其傳遞至 --use-related-website-set

進一步瞭解如何使用旗標執行 Chromium

--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/

範例

如要在本機啟用相關網站組合,您必須在 chrome://flags 中啟用 test-third-party-cookie-phaseout,並透過命令列啟動 Chrome,並使用 --use-related-website-set 標記和 JSON 物件,其中包含組合成員的網址。

--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/

確認您有權存取跨網站 Cookie

從要測試的網站呼叫 API (rSA 或 rSAFor),並驗證跨網站 Cookie 的存取權。

請按照下列步驟宣告網域之間的關係,並指定這些網域屬於哪個子集。

1. 找出 RWS

找出相關網域,包括將納入相關網站集的主要網域成員網域。並找出每個集合成員所屬的子集類型

2. 建立 RWS 提交內容

建立 GitHub 存放區的本機副本 (複製或分支)。在新的分支中,變更 related_website_sets.JSON 檔案,以反映您的設定。如要確保組合具有正確的 JSON 格式和結構,您可以使用 JSON 產生器工具

3. 確保 RWS 符合技術規定

確認已設定集合體格式規定集合驗證規定

4. 在本機測試 RWS

在建立提取要求 (PR) 來提交套件前,請在本機測試提交內容,確保其通過所有必要的檢查。

5. 提交 RWS

如要提交相關網站集,請建立對 related_website_sets.JSON 檔案的 PR,Chrome 會在該檔案中代管標準的相關網站集清單。(您必須擁有 GitHub 帳戶才能建立 PR,且必須先簽署《Contributor's License Agreement (CLA)》,才能為清單做出貢獻。)

建立 PR 後,系統會完成一系列檢查,確保您已符合步驟 3 的規定,例如確認您已簽署 CLA,且 .well-known 檔案有效。

如果成功,PR 會指出檢查已通過。每週一次 (星期二中午 12 點美東時間),系統會手動將已核准的提交要求批次合併至標準的相關網站集合清單。如果任何檢查失敗,提交者會收到 GitHub 的 PR 失敗通知。提交者可以修正錯誤並更新 PR,但請注意:

  • 如果提交失敗,系統會顯示錯誤訊息,提供提交失敗的原因。(範例)。
  • 所有套件提交作業的技術檢查都會在 GitHub 上進行,因此,所有因技術檢查而導致的提交失敗,都會顯示在 GitHub 上。

企業政策

Chrome 提供兩項政策,滿足企業使用者的需求:

  • 如果系統無法與相關網站組整合,您可以使用 RelatedWebsiteSetsEnabled 政策,在所有 Chrome 企業執行個體中停用相關網站組功能。
  • 有些企業系統有僅供內部使用的網站 (例如內部網),其可註冊網域與相關網站組的網域不同。如果他們需要將這些網站視為相關網站集的一部分,但不想公開這些網站 (因為網域可能屬於機密資訊),他們可以使用 RelatedWebsiteSetsOverrides 政策擴充或覆寫公開的相關網站集清單。

Chrome 會根據是否指定 replacemementsadditions,以兩種方式之一解析公開和企業集合的任何交集。

例如,針對公開集合 {primary: A, associated: [B, C]}

replacements 組: {primary: C, associated: [D, E]}
企業集合會吸收一般網站,形成新的集合。
產生的集合: {primary: A, associated: [B]}
{primary: C, associated: [D, E]}
additions 組: {primary: C, associated: [D, E]}
公開和企業組合會合併。
產生的集合: {primary: C, associated: [A, B, D, E]}

「使用者提示」和「使用者手勢」

「使用者提示」和「使用者手勢」是不同的概念。Chrome 不會向使用者顯示權限提示,但仍要求使用者與網頁互動。在授予權限前,Chrome 會要求使用者做出手勢,也稱為「使用者互動」或「使用者啟用」。這是因為根據網路平台設計原則,在「相關網站集」內容 (即 requestStorageAccess()) 以外使用 Storage Access API 時,也需要使用者手勢。

存取其他網站的 Cookie 或儲存空間

相關網站組合不會合併不同網站的儲存空間,只是讓您更輕鬆地 (不必提示) 撥打 requestStorageAccess() 電話。相關網站組合只會降低使用者使用 Storage Access API 的阻礙,但不會指示在存取權還原後該做什麼。如果 A 和 B 是同一組相關網站中的不同網站,且 A 嵌入 B,則 B 可以呼叫 requestStorageAccess(),並取得第一方儲存空間的存取權,而無須提示使用者。相關網站集不會執行任何跨網站通訊。舉例來說,設定相關網站組不會導致屬於 B 的 Cookie 開始傳送至 A。如果您想分享這項資料,就必須自行分享,例如從 B 內嵌框將 window.postMessage 傳送至 A 框架。

相關網站組合不允許在未叫用任何 API 的情況下,存取隱含未分割的 Cookie。根據預設,套件內不會提供跨網站 Cookie;相關網站套件只允許套件內的網站略過 Storage Access API 權限提示。如果 iframe 想要存取自己的 Cookie,就必須呼叫 document.requestStorageAccess(),否則頂層網頁可以呼叫 document.requestStorageAccessFor()

提供意見

您可以在 GitHub 上提交一組內容,並使用 Storage Access API 和 requestStorageAccessFor API,分享您在這個過程中遇到的任何問題。

如要加入相關網站集的討論,請按照下列步驟操作: