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

相關網站集 (RWS) 是一種網路平台機制,可協助瀏覽器瞭解網域集合之間的關係。因此,瀏覽器可以做出重要決策,啟用特定網站功能 (例如是否允許存取跨網站 Cookie),並向使用者顯示這項資訊。

Chrome 淘汰了第三方 Cookie,目標是保留網路上的重要用途,同時加強保護使用者的隱私權。舉例來說,許多網站需要透過多個網域才能提供單一的使用者體驗。機構可能想針對多種使用情境 (例如代管圖片或影片的服務網域,或服務網域) 維護不同的頂層網域。相關網站集可讓網站藉由特定控制功能,跨網域共用資料。

整體來說,相關網站集是一組網域,其中只有一個「設定主要」,且可能包含多個「設定成員」。

在以下範例中,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

瀏覽器支援

  • 119
  • 85
  • 65
  • 11.1

資料來源

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

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

如果封鎖第三方 Cookie,但已啟用相關網站集 (RWS),Chrome 會自動在 RWS 內授予權限,並向使用者顯示提示。「在 RWS 內結構定義」是指一種結構定義,例如 iframe, iframe 會將嵌入的網站和頂層網站位於同一個 RWS。

查看及要求儲存空間存取權

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

此方法會傳回 promise,並以布林值表示文件是否已經存取其 Cookie。如果 iframe 與頂層頁框相同,則承諾也會傳回 true。

如要要求跨網站情境嵌入網站的 Cookie 存取權,可以使用 Document.requestStorageAccess() (rSA)。

requestStorageAccess() API 的設計是在 iframe 內呼叫。該 iframe 必須只接收使用者互動 (所有瀏覽器都需要「使用者手勢」),但 Chrome 還要求在過去 30 天內,要求使用者造訪擁有該 iframe 且與該網站特別互動的網站 (而非在 iframe 中與網站互動)。

如果授予儲存空間存取權,requestStorageAccess() 會傳回承諾,可解決。如果存取作業因任何原因遭拒,承諾會遭到拒絕,並註明原因。

在 Chrome 中使用 requestStorageAccessFor

瀏覽器支援

  • 119
  • 119
  • x
  • x

資料來源

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

因此,針對使用跨網站圖片或需要 Cookie 的指令碼標記的頂層網站,卻讓他們無法採用 Storage Access API。

為解決此問題,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 為何,絕不會在跨網站結構定義中共用這些 Cookie。

安全性

針對 rSAFor,子資源要求需要跨源資源共享 (CORS) 標頭或資源的 crossorigin 屬性,確保使用者明確選擇採用這些資源。

導入範例

透過內嵌的跨來源 iframe 要求存取儲存空間

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

檢查您是否擁有儲存空間存取權

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

如果承諾能解決,您可以在跨網站結構定義中存取儲存空間。如果解決方法為 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 或跨源屬性的 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,並透過包含 --use-related-website-set 標記的指令列啟動 Chrome,並以內含組合網址的 JSON 物件啟動 Chrome。

--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. 找出相關網域,包括要納入相關網站集的設定主要設定成員。此外也識別每個集合成員所屬的子集類型
  2. 確認已符合設定規定設定驗證規定
  3. 使用正確的 JSON 格式宣告相關網站集。
  4. 提交相關網站集的提取要求 (PR)related_website_sets.JSON,供 Chrome 代管標準相關網站集清單。(如要建立 PR,需要擁有 GitHub 帳戶,而且您必須簽署貢獻者授權協議 (CLA),才能編輯清單)。

建立 PR 後,系統會執行一系列的檢查,確認步驟 2 的要求都已就緒。

如果成功,PR 會指出已通過檢查。已核准的 PR 將每週手動合併至標準相關網站集清單一次 (美國東部標準時間星期二中午 12 點)。

如果任何檢查失敗,提交者會在 GitHub 上看到 PR 失敗通知。提交者可以修正錯誤及更新公關,請注意以下事項:

  • PR 失敗時,錯誤訊息會提供額外資訊,說明提交失敗的原因 (示例)。
  • 所有控管組合提交項目的技術檢查作業都會在 GitHub 上進行,因此之後因技術檢查而發生的所有提交錯誤都能在 GitHub 上查看。

企業政策

為了滿足企業使用者的需求,Chrome 設有幾項企業政策:

  • 如果系統可能無法與「相關網站集」整合,則可根據 RelatedWebsiteSetsEnabled 政策,在 Chrome 的所有企業執行個體中停用相關網站集功能。
  • 某些企業系統中,只有內部網站 (例如內部網路) 擁有可註冊的網域,而這些網域與相關網站集中的網域不同。如果他們需要將這些網站視為其相關網站集的一部分,但不對外公開 (因為網域可能含有機密內容),他們可以運用 RelatedWebsiteSetsOverrides 政策來擴充或覆寫公開的相關網站集清單。

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

「使用者提示」和「使用者手勢」並不相同。針對位於相同相關網站集的網站,Chrome 不會向使用者顯示權限提示,但 Chrome 仍會要求使用者與網頁互動。在授予權限前,Chrome 會要求使用使用者手勢 (又稱為「使用者互動」或「使用者啟用」)。這是因為在相關網站集結構定義 (即 requestStorageAccess()) 以外使用 Storage Access API 時,也需要使用者手勢,因為網路平台設計原則

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

相關網站集不會合併不同網站的儲存空間,只會讓 requestStorageAccess() 呼叫變得更簡單 (無提示)。相關網站集只會降低使用 Storage Access API 的使用者的不便,但不會決定存取權恢復後該怎麼做。如果 A 和 B 是同一個相關網站集中的不同網站,且 A 嵌入是 B,那麼 B 可以呼叫 requestStorageAccess() 並取得第一方儲存空間,而不需要提示使用者。相關網站集不會執行任何跨網站通訊。舉例來說,設定相關網站集並不會導致屬於 B 的 Cookie 開始傳送至 A。如要共用這些資料,您必須自行分享,例如,將 window.postMessage 從 B iframe 傳送至影格。

相關網站集不允許在未叫用任何 API 的情況下,使用隱含的未分區 Cookie 存取。系統不會在集合中預設提供跨網站 Cookie;相關網站集只會允許該集合中的網站略過 Storage Access API 權限提示。iframe 要存取其 Cookie 時,必須呼叫 document.requestStorageAccess(),或者頂層頁面可以呼叫 document.requestStorageAccessFor()

提供意見

您可以在 GitHub 上提交集,並使用 Storage Access API 和 requestStorageAccessFor API 分享經驗和所遇到的任何問題。

如何加入相關網站集的討論: