Storage Access API

為了減少跨網站追蹤,Chrome 將逐步停止支援第三方 Cookie。對於需要在嵌入式環境中使用 Cookie 的網站和服務,讓使用者歷程這類的驗證作業卻是一大挑戰。Storage Access API (SAA) 可讓這些用途繼續運作,同時盡量限制跨網站追蹤。

導入狀態

瀏覽器支援

  • 119
  • 85
  • 65
  • 11.1

資料來源

所有主要瀏覽器都能使用 Storage Access API,但是不同瀏覽器之間的導入有些微差異。我們在本文的相關章節中已強調這些差異。

我們會繼續努力解決所有最新的封鎖問題,再將 API 標準化

什麼是 Storage Access API?

Storage Access API 是一種 JavaScript API,可讓 iframe 在瀏覽器設定拒絕存取的情況下要求儲存空間存取權限。如果嵌入的用途需要載入跨網站資源,就可以視需要使用 API 向使用者要求存取權限。

如果儲存空間要求獲得儲存,iframe 將可存取其跨網站 Cookie,當使用者以頂層網站的方式造訪 Cookie 時也可以使用該 Cookie。

Storage Access API 可提供特定的跨網站 Cookie 存取,對使用者幾乎沒有負擔,同時又能防止像使用者追蹤常用的跨網站 Cookie 存取一般。

用途

部分第三方嵌入項目需要跨網站 Cookie 的存取權,才能為使用者提供更優質的體驗;而這是因為第三方 Cookie 遭淘汰後即無法使用。

用途包括:

  • 需要登入工作階段詳細資料的嵌入式留言小工具。
  • 需要登入工作階段詳細資料的社群媒體「喜歡」按鈕。
  • 需要登入工作階段詳細資料的內嵌文件。
  • 提供給嵌入影片的優質體驗 (例如不向已登入的使用者顯示廣告,或是瞭解使用者的隱藏式輔助字幕偏好設定,或限制某些影片類型)。
  • 內嵌付款系統。

其中許多使用情境都涉及在嵌入式 iframe 中持續登入。

在其他 API 上使用 Storage Access API 的時機

Storage Access API 是第三方 Cookie 的替代方案之一,因此請務必瞭解這個 API 的使用時機。適用於以下兩者的用途:

  • 使用者會與嵌入的內容互動,也就是說,它不是被動式 iframe 或隱藏的 iframe。
  • 使用者已在頂層環境造訪嵌入的來源,也就是該來源並未嵌入其他網站。

以下 API 適用於多種用途:

  • 具有獨立分區狀態的 Cookie (CHIPS) 可讓開發人員選擇將 Cookie 啟用「分區」儲存空間,因為每個頂層網站都有獨立的 Cookie jar。舉例來說,第三方網頁即時通訊小工具可能需要設定 Cookie,才能儲存工作階段資訊。每個網站都會儲存工作階段資訊,因此小工具設定的 Cookie 不需在其他內嵌它的網站上存取。如果嵌入的第三方小工具需要在不同來源分享相同資訊 (例如已登入的工作階段詳細資料或偏好設定),則 Storage Access API 會派上用場。
  • 相關網站集 (RWS) 可讓機構宣告網站間的關係,讓瀏覽器允許有限的第三方 Cookie 存取特定用途。網站仍需透過 Storage Access API 要求存取權,但針對該組合中的網站,則可直接授予存取權,無須使用者提示。
  • Federated Credential Management (FedCM) 是保護聯合身分識別服務的隱私保護做法。Storage Access API 會處理登入後存取 Cookie 的情形。針對某些用途,FedCM 提供了 Storage Access API 的替代解決方案,因為其具有更注重登入機制的瀏覽器提示,可能會比較好使用。不過,採用 FedCM 通常需要對程式碼進行其他變更,例如支援其 HTTP 端點。
  • 此外,我們也提供了反詐欺廣告相關評估 API,而 Storage Access API 不得用來解決這些問題。

使用 Storage Access API

Storage Access API 有兩種承諾的方法:

這個程式庫也整合了 Permissions API。這樣就能在第三方情境中檢查儲存空間存取權的狀態,指明是否要自動授予 document.requestStorageAccess() 呼叫:

使用 hasStorageAccess() 方法

網站首次載入時,可使用 hasStorageAccess() 方法檢查是否已授予第三方 Cookie 存取權。

// Set a hasAccess boolean variable which defaults to false.
let hasAccess = false;

async function handleCookieAccessInit() {
  if (!document.hasStorageAccess) {
    // Storage Access API is not supported so best we can do is
    // hope it's an older browser that doesn't block 3P cookies.
    hasAccess = true;
  } else {
    // Check whether access has been granted via the Storage Access API.
    // Note on page load this will always be false initially so we could be
    // skipped in this example, but including for completeness for when this
    // is not so obvious.
    hasAccess = await document.hasStorageAccess();
    if (!hasAccess) {
      // Handle the lack of access (covered later)
    }
  }
  if (hasAccess) {
    // Use the cookies.
  }
}
handleCookieAccessInit();

系統只會在呼叫 requestStorageAccess(), 後授予 iframe 文件儲存空間存取權,因此 hasStorageAccess() 一開始一律會傳回 false,除非同一個 iframe 中的另一個相同來源文件已獲得存取權。授予項目會保留在 iframe 中相同來源瀏覽的期間,專門允許在 HTML 文件初始要求中包含 Cookie 的存取之後重新載入頁面。

使用 requestStorageAccess() 方法

如果 iframe 無法存取,您可能需要使用 requestStorageAccess() 方法要求存取權:

if (!hasAccess) {
  try {
    await document.requestStorageAccess();
  } catch (err) {
    // Access was not granted and it may be gated behind an interaction
    return;
  }
}

首次提出要求時,使用者可能需要透過瀏覽器提示核准此存取權,之後這項承諾會如期解決;如果使用 await,則系統會拒絕並將例外狀況遭到拒絕。

為避免濫用,這個瀏覽器提示只會在使用者進行互動後顯示。這就是為什麼一開始需要透過使用者啟用的事件處理常式呼叫 requestStorageAccess(),而不是在 iframe 載入時立即呼叫:

async function doClick() {

  // Only do this extra check if access hasn't already been given
  // based on the hasAccess variable.
  if (!hasAccess) {
    try {
      await document.requestStorageAccess();
      hasAccess = true; // Can assume this was true if above did not reject.
    } catch (err) {
      // Access was not granted.
      return;
    }
  }

  if (hasAccess) {
    // Use the cookies
  }
}

document.querySelector('#my-button').addEventListener('click', doClick);

權限提示

當使用者第一次按下按鈕時,瀏覽器提示會自動顯示 (通常位於網址列)。以下是 Chrome 的提示範例,其他瀏覽器的使用者介面則類似:

Chrome Storage Access API 權限提示的螢幕截圖
Chrome 的 Storage Access API 權限提示

瀏覽器可能會略過提示,並在特定情況下自動授予權限:

  • 如果您在接受提示後的 30 天內曾使用該網頁和 iframe。
  • 如果嵌入的 iframe 屬於「相關網站集」的一部分,
  • 在 Firefox 中,對於已知網站 (也就是您頂層互動的網站) 在前五次嘗試時,系統也會略過提示。

此外,在某些情況下,這個方法可能會自動拒絕,而不會在特定情況下顯示提示:

  • 如果使用者從未瀏覽過以 iframe 為頂層文件 (而非 iframe) 擁有的網站,並與這類網站互動。也就是說,Storage Access API 僅適用於使用者曾在第一方環境中造訪的嵌入式網站。
  • 如果在使用者互動事件以外的地方呼叫 requestStorageAccess() 方法,但未事先經過提示核准,即出現該方法。

當使用者初次使用時,系統會提示使用者,但後續造訪時不需要提示,也不必在 Chrome 和 Firefox 中進行互動,就能解析 requestStorageAccess()。請注意,Safari 一律需要使用者互動。

使用者可能會在不需提示或互動的情況下存取 Cookie,因此通常可以在使用者於載入網頁 (Chrome 和 Firefox) 的瀏覽器上呼叫 requestStorageAccess(),先取得第三方 Cookie 存取權。這樣一來,您就能立即存取第三方跨網站 Cookie,並在使用者與 iframe 互動前提供完整體驗。在某些情況下,相較於等待使用者互動,這項功能可以提供更優質的使用者體驗。

使用 storage-access 權限查詢

如要檢查是否能在沒有使用者互動的情況下授予存取權,可以檢查 storage-access 的權限狀態,並且只在使用者不需要採取任何動作的情況下,提前呼叫 requestStoreAccess() 呼叫,而在需要互動時,使其失敗。

此外,您也能藉由顯示不同內容 (例如登入按鈕) 預先處理提示的需求。

下列程式碼會將 storage-access 權限檢查新增至上述範例:

// Set a hasAccess boolean variable which defaults to false except for
// browsers which don't support the API - where we assume
// such browsers also don't block third-party cookies.
let hasAccess = false;

async function hasCookieAccess() {
  // Check if Storage Access API is supported
  if (!document.requestStorageAccess) {
    // Storage Access API is not supported so best we can do is
    // hope it's an older browser that doesn't block 3P cookies.
    return true;
  }

  // Check if access has already been granted
  if (await document.hasStorageAccess()) {
    return true;
  }

  // Check the storage-access permission
  // Wrap this in a try/catch for browsers that support the
  // Storage Access API but not this permission check
  // (e.g. Safari and older versions of Firefox).
  let permission;
  try {
    permission = await navigator.permissions.query(
      {name: 'storage-access'}
    );
  } catch (error) {
    // storage-access permission not supported. Assume no cookie access.
    return false;
  }

    if (permission) {
    if (permission.state === 'granted') {
      // Permission has previously been granted so can just call
      // requestStorageAccess() without a user interaction and
      // it will resolve automatically.
      try {
        await document.requestStorageAccess();
        return true;
      } catch (error) {
        // This shouldn't really fail if access is granted, but return false
        // if it does.
        return false;
      }
    } else if (permission.state === 'prompt') {
      // Need to call requestStorageAccess() after a user interaction
      // (potentially with a prompt). Can't do anything further here,
      // so handle this in the click handler.
      return false;
          } else if (permission.state === 'denied') {
            // Currently not used. See:
      // https://github.com/privacycg/storage-access/issues/149
      return false;
          }
    }

  // By default return false, though should really be caught by one of above.
  return false;
}

async function handleCookieAccessInit() {
  hasAccess = await hasCookieAccess();

  if (hasAccess) {
    // Use the cookies.
  }
}

handleCookieAccessInit();

沙箱 iframe

沙箱 iframe 中使用 Storage Access API 時,需要下列沙箱權限:

  • 必須具備 allow-storage-access-by-user-activation 權限,才能存取 Storage Access API。
  • 需要 allow-scripts 才能使用 JavaScript 呼叫 API。
  • 必須具備 allow-same-origin 權限,才能存取相同來源的 Cookie 和其他儲存空間。

例如:

<iframe sandbox="allow-storage-access-by-user-activation
                 allow-scripts
                 allow-same-origin"
        src="..."></iframe>

如要在 Chrome 中使用 Storage Access API 存取,必須使用下列兩個屬性設定跨網站 Cookie:

  • SameSite=None:這是將 Cookie 標示為跨網站的必要步驟
  • Secure:可確保使用者只能存取 HTTPS 網站設定的 Cookie。

在 Firefox 和 Safari 中,Cookie 會預設為 SameSite=None,且不會限制 SSA 使用 Secure Cookie,因此不需要提供這些屬性。建議您明確提供 SameSite 屬性,並一律使用 Secure Cookie。

頂層頁面存取權

Storage Access API 的用途是允許存取嵌入式 iframe 中的第三方 Cookie。

如果頂層網頁要求存取第三方 Cookie,也有一些用途。舉例來說,假如圖片或指令碼受到 Cookie 限制,網站擁有者可能想直接將網站納入頂層文件,而非 iframe 中。為解決這個問題,Chrome 提議使用 Storage Access API 的擴充功能,並新增了 requestStorageAccessFor() 方法。

requestStorageAccessFor() 方法

瀏覽器支援

  • 119
  • 119
  • x
  • x

資料來源

requestStorageAccessFor() 方法的運作方式與 requestStorageAccess() 類似,但適用於頂層資源。只能用於相關網站集中的網站,以禁止授予第三方 Cookie 的一般存取權。

如要進一步瞭解如何使用 requestStorageAccessFor(),請參閱「相關網站集:開發人員指南」。

top-level-storage-access 權限查詢

瀏覽器支援

  • 119
  • 119
  • x
  • x

storage-access 權限類似,有 top-level-storage-access 權限可檢查是否能授予 requestStorageAccessFor() 的存取權。

Storage Access API 與 RWS 搭配使用時有何不同?

將相關網站集與 Storage Access API 搭配使用時,系統會提供特定額外功能,詳情如下表所示:

沒有 RWS RWS 設計
須透過使用者手勢發出儲存空間存取權要求
要求使用者在授予存取權前,必須在頂層情境中造訪要求的儲存空間來源
使用者可以略過首次使用者提示
如果先前已授予存取權,則不必呼叫 requestStorageAccess
自動授予相關網站中其他網域的存取權
支援requestStorageAccessFor 頂層網頁存取權
在未採用相關網站集的情況下,使用 Storage Access API 的差異

示範:設定及存取 Cookie

以下示範在示範的第二個網站上,如何在嵌入式頁框中存取自己設定的 Cookie:

storage-access-api-demo.glitch.me

如要進行示範,瀏覽器必須停用第三方 Cookie:

  • Chrome 118 以上版本 (已設定 chrome://flags/#test-third-party-cookie-phaseout 標記) 並重新啟動瀏覽器。
  • Firefox
  • Safari

資源