Storage Access API

ブラウザ、ユーザー設定、ストレージ パーティショニングによるサードパーティ Cookie のブロックは、埋め込みコンテキストで Cookie やその他のストレージを使用するサイトやサービスで、認証などのユーザー ジャーニーにおいて課題となります。Storage Access API(SAA)を使用すると、クロスサイト トラッキングを可能な限り制限しながら、これらのユースケースを引き続き使用できます。

実装ステータス

対応ブラウザ

  • Chrome: 119。
  • Edge: 85。
  • Firefox: 65。 <ph type="x-smartling-placeholder">
  • Safari: 11.1。

ソース

Storage Access API はすべての主要なブラウザで使用できますが、ブラウザによって実装に若干の違いがあります。これらの違いについては、この記事の関連するセクションで説明しています。

API の標準化の前に、残っている問題をすべて解決する取り組みが継続されています。

Storage Access API とは何ですか?

Storage Access API は、ブラウザの設定でアクセスが拒否される場合に、iframe がストレージへのアクセス権限をリクエストできるようにする JavaScript API です。クロスサイト リソースの読み込みに依存するユースケースを含む埋め込みでは、必要に応じて API を使用してユーザーにアクセス権をリクエストできます。

ストレージ リクエストが許可されると、iframe はパーティション分割されていない Cookie とストレージにアクセスできるようになります。これらの Cookie とストレージは、ユーザーがトップレベル サイトとしてアクセスする場合にも使用できます。

Storage Access API を使用すると、エンドユーザーの負担を最小限に抑えながら、特定のパーティション分割されていない Cookie とストレージへのアクセスを提供すると同時に、ユーザーのトラッキングでよく使われるようなパーティション分割されていない一般的な Cookie やストレージへのアクセスを防止できます。

ユースケース

一部のサードパーティ埋め込みでは、ユーザー エクスペリエンスを向上させるために、パーティション分割されていない Cookie またはストレージへのアクセスが必要となります。これは、サードパーティ Cookie が制限され、ストレージ パーティショニングが有効になっている場合は利用できなくなります。

ユースケースの例:

  • ログイン セッションの詳細を必要とする埋め込みコメント ウィジェット。
  • ソーシャル メディアの「高評価」ログイン セッションの詳細情報を要求するボタン
  • ログイン セッションの詳細情報を必要とする埋め込みドキュメント。
  • 埋め込み動画の高度な機能(たとえば、ログイン ユーザーには広告を表示しない、字幕に関するユーザー設定を把握する、特定の動画タイプを制限するなど)。
  • 組み込み型の決済システム。

これらのユースケースの多くは、埋め込み iframe でログイン アクセスを持続させます。

他の API ではなく Storage Access API を使用する場合

Storage Access API は、パーティショニングされていない Cookie とストレージを使用する場合の代替手段の 1 つであるため、他の API と比較して、この API を使用するタイミングを理解することが重要です。次の両方に該当するユースケースを対象としています。

  • ユーザーは埋め込みコンテンツを操作します。つまり、パッシブ iframe や隠し iframe ではありません。
  • ユーザーがトップレベル コンテキストで埋め込まれたオリジンにアクセスした(そのオリジンが別のサイトに埋め込まれていないとき)。

さまざまなユースケースに対応する代替 API があります。

  • Cookies Having Independent Partitioned State(CHIPS)により、デベロッパーは、トップレベル サイト別のストレージに「パーティション化して」保存される Cookie にオプトインできます。たとえば、サードパーティのウェブチャット ウィジェットでは、Cookie の設定によってセッション情報を保存することがあります。セッション情報はサイトごとに保存されるため、ウィジェットで設定された Cookie が埋め込まれている他のウェブサイトからアクセスする必要はありません。Storage Access API は、埋め込まれたサードパーティ製ウィジェットが、異なるオリジンで同じ情報(ログイン セッションの詳細や設定など)を共有することに依存している場合に役立ちます。
  • ストレージ パーティショニングは、クロスサイト iframe で既存の JavaScript ストレージ メカニズムを使用し、基盤となるストレージをサイトごとに分割する方法です。これにより、あるウェブサイトの埋め込みストレージが、他のウェブサイトにある同じ埋め込みストレージからアクセスされるのを防ぐことができます。
  • 関連ウェブサイト セット(RWS)は、組織がサイト間の関係を宣言して、ブラウザが制限されているパーティショニングされていない Cookie とストレージへの特定の目的でのアクセスを許可できるようにする方法です。サイトは引き続き Storage Access API でアクセスをリクエストする必要がありますが、このセット内のサイトについては、ユーザーにプロンプトを表示せずにアクセスを許可できます。
  • Federated Credential Management(FedCM)は、フェデレーション ID サービスのプライバシー保護アプローチです。Storage Access API は、パーティション分割されていない Cookie へのアクセスとログイン後のストレージを処理します。ユースケースによっては、FedCM が Storage Access API の代替ソリューションとして機能します。ログイン指向のブラウザ プロンプトを備えているため、優先される場合があります。ただし、FedCM を導入するには、通常、コードに追加の変更(HTTP エンドポイントのサポートなど)が必要になります。
  • 不正行為防止広告関連測定 API も存在しますが、Storage Access API はこれらの懸念に対処することを目的としたものではありません。

Storage Access API を使用する

Storage Access API には、Promise ベースのメソッドが 2 つあります。

また、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 using 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();

iframe ドキュメントへのストレージ アクセスは、requestStorageAccess(), が呼び出された後にのみ付与されるため、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;
  }
}

これが初めてリクエストされたときに、ユーザーはブラウザ プロンプトでこのアクセスを承認する必要がある場合があります。その後 Promise が解決されるか、await が使用されている場合は拒否されて例外が発生します。

不正使用を防ぐため、このブラウザ プロンプトはユーザーの操作後にのみ表示されます。そのため、iframe の読み込み直後ではなく、ユーザーが開始したイベント ハンドラから requestStorageAccess() を最初に呼び出す必要があります。

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 requestStorageAccess() did not reject.
    } catch (err) {
      // Access was not granted.
      return;
    }
  }

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

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

Cookie ではなくローカル ストレージを使用する必要がある場合は、次の操作を行います。

let handle = null;

async function doClick() {
  if (!handle) {
    try {
      handle = await document.requestStorageAccess({localStorage: true});
    } catch (err) {
      // Access was not granted.
      return;
    }
  }

  // Use handle to access unpartitioned local storage.
  handle.localStorage.setItem('foo', 'bar');
}

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

権限プロンプト

ユーザーが初めてボタンをクリックしたときに、ブラウザ プロンプトで 通常はアドレスバーに表示されます。次のスクリーンショット に Chrome のプロンプトの例を示します。ただし、他のブラウザでも同様の UI があります。

Chrome Storage Access API の権限プロンプト
Chrome の Storage Access API 権限プロンプト

特定の状況では、ブラウザによってプロンプトがスキップされ、権限が自動的に付与されることがあります。

  • プロンプトの承認後、過去 30 日間にページと iframe が使用されているかどうか。
  • 埋め込み iframe が関連ウェブサイト セットの一部である場合。
  • Firefox では、既知のウェブサイト(最上位レベルで操作したウェブサイト)でも、最初の 5 回の試行ではプロンプトがスキップされます。

また、特定の状況では、プロンプトを表示せずにメソッドが自動的に拒否される場合があります。

  • iframe 内ではなく、最上位のドキュメントとして iframe を所有しているサイトにユーザーがアクセスしたことがなく、操作したことがない場合。つまり、Storage Access API は、ユーザーが以前にファーストパーティのコンテキストでアクセスした埋め込みサイトにのみ有用です。
  • 操作後のプロンプトに対する事前の承認なしに、ユーザー操作イベントの外部で requestStorageAccess() メソッドが呼び出された場合。

初回使用時にはユーザーにプロンプトが表示されますが、Chrome と Firefox では、それ以降のアクセスではプロンプトが表示されず、ユーザー操作も必要ありません。Safari では常にユーザーの操作が必要です。

<ph type="x-smartling-placeholder">

Cookie とストレージへのアクセス権は、プロンプトやユーザーの操作なしで付与される場合があるため、多くの場合、ページ読み込み時に requestStorageAccess() を呼び出すことで、この機能をサポートしているブラウザ(Chrome と Firefox)でユーザーが操作を行う前に、パーティション分割されていない Cookie またはストレージへのアクセス権を取得できます。これにより、ユーザーが iframe を操作する前でも、パーティション分割されていない Cookie やストレージにすぐにアクセスして、完全なエクスペリエンスを提供できます。これにより、状況によっては、ユーザーの操作を待つよりもユーザー エクスペリエンスが向上することがあります。

storage-access 権限クエリを使用する

ユーザーの操作なしでアクセス権を付与できるかどうかを確認するには、storage-access 権限のステータスを確認し、ユーザー操作が不要な場合にのみ requestStoreAccess() を早期に呼び出すようにします。呼び出して、操作が必要な場合に失敗することはありません。

また、さまざまなコンテンツ(ログインボタンなど)を表示することで、事前のプロンプトの必要性に対処することもできます。

<ph type="x-smartling-placeholder">

次のコードは、前の例に 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 earlier 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') {
            // Not used: see https://github.com/privacycg/storage-access/issues/149
      return false;
          }
    }

  // By default return false, though should really be caught by earlier tests.
  return false;
}

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

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

handleCookieAccessInit();

サンドボックス化された iframe

サンドボックス化された iframe で Storage Access API を使用する場合は、次のサンドボックス権限が必要です。

  • Storage Access API へのアクセスを許可するには、allow-storage-access-by-user-activation が必要です。
  • JavaScript を使用して API を呼び出すには、allow-scripts が必要です。
  • allow-same-origin は、同じオリジンの Cookie やその他のストレージへのアクセスを許可するために必要です。

例:

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

Chrome で Storage Access API を使用してアクセスするには、次の 2 つの属性でクロスサイト Cookie を設定する必要があります。

  • SameSite=None - Cookie をクロスサイトとしてマークするために必要
  • Secure - HTTPS サイトによって設定された Cookie のみにアクセスできるようにします。

Firefox と Safari では、Cookie はデフォルトで SameSite=None に設定され、SAA を Secure Cookie に制限しないため、これらの属性は必要ありません。SameSite 属性を明示的に指定し、常に Secure Cookie を使用することをおすすめします。

トップレベルのページへのアクセス

Storage Access API は、埋め込み iframe 内でサードパーティ Cookie へのアクセスを有効にすることを目的としています。

最上位ページでサードパーティ Cookie へのアクセスが必要な場合もあります。たとえば、Cookie によって制限されている画像やスクリプトなどです。サイト所有者は、iframe ではなくトップレベル ドキュメントに直接含めることを希望する場合があります。このユースケースに対応するため、Chrome では requestStorageAccessFor() メソッドを追加する Storage Access API の拡張を提案しています。

requestStorageAccessFor() メソッド

対応ブラウザ

  • Chrome: 119。
  • Edge: 119.
  • Firefox: サポートされていません。 <ph type="x-smartling-placeholder">
  • Safari: サポートされていません。 <ph type="x-smartling-placeholder">

ソース

requestStorageAccessFor() メソッドは requestStorageAccess() と同様の方法で動作しますが、最上位リソースに対して動作します。サードパーティ Cookie への一般的なアクセス権の付与を防ぐために、関連ウェブサイト セット内のサイトでのみ使用できます。

requestStorageAccessFor() の使用方法について詳しくは、関連ウェブサイト セット: デベロッパー ガイドをご覧ください。

top-level-storage-access 権限クエリ

対応ブラウザ

  • Chrome: サポートされていません。 <ph type="x-smartling-placeholder">
  • Edge: サポートされていません。 <ph type="x-smartling-placeholder">
  • Firefox: サポートされていません。
  • Safari: サポートされていません。 <ph type="x-smartling-placeholder">

storage-access 権限と同様に、requestStorageAccessFor() にアクセス権を付与できるかどうかを確認する top-level-storage-access 権限があります。

RWS で使用する場合の Storage Access API の違い

関連ウェブサイト セットを Storage Access API で使用する場合、次の表に示す追加機能が使用できます。

RWS なし RWS 対応
ストレージへのアクセス リクエストを開始するにはユーザー操作が必要
アクセス権を付与する前に、最上位のコンテキストでリクエストされたストレージ オリジンにアクセスする必要がある
初回ユーザーのプロンプトをスキップできる
アクセス権がすでに付与されている場合は requestStorageAccess を呼び出す必要はありません。
関連ウェブサイト サイトで他のドメインへのアクセスを自動的に許可する
最上位レベルのページへのアクセスをrequestStorageAccessFor サポートします
Storage Access API を使用する場合、関連ウェブサイト セットを使用する場合と使用しない場合の違い

デモ: Cookie の設定とアクセス

次のデモは、デモの最初の画面で設定した Cookie に、デモの 2 番目のサイトの埋め込みフレームでアクセスする方法を示しています。

storage-access-api-demo.glitch.me

このデモでは、サードパーティ Cookie が無効になっているブラウザが必要です。

  • chrome://flags/#test-third-party-cookie-phaseout フラグを設定し、ブラウザを再起動した Chrome 118 以降。
  • Firefox
  • Safari

デモ: ローカル ストレージの設定

次のデモは、Storage Access API を使用して、サードパーティの iframe からパーティショニングされていないブロードキャスト チャネルにアクセスする方法を示しています。

https://saa-beyond-cookies.glitch.me/

このデモを行うには、test-third-party-cookie-phaseout フラグを有効にした Chrome 125 以降が必要です。

リソース