ブラウザ、ユーザー設定、ストレージ パーティショニングによるサードパーティ Cookie のブロックは、埋め込みコンテキストで Cookie やその他のストレージに依存するサイトやサービスにとって、認証などのユーザー ジャーニーに課題をもたらします。Storage Access API(SAA)を使用すると、クロスサイト トラッキングを可能な限り制限しながら、これらのユースケースを継続して使用できます。
実装ステータス
Storage Access API はすべての主要なブラウザで使用できますが、ブラウザによって実装に若干の違いがあります。これらの違いについては、この記事の関連するセクションで説明しています。
API の標準化に向けて、残りのブロックの問題をすべて解決するための作業が継続されています。
Storage Access API とは何ですか?
Storage Access API は、ブラウザ設定によってアクセスが拒否される場合に、iframes からストレージのアクセス権限をリクエストできるようにする JavaScript API です。クロスサイト リソースの読み込みに依存するユースケースの埋め込みでは、API を使用して、必要に応じてユーザーにアクセス権限をリクエストできます。
ストレージ リクエストが承認されると、iframe はパーティション化されていない 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 つあります。
Document.hasStorageAccess()
(Chrome 125 以降は新しい名前Document.hasUnpartitionedCookieAccess()
でも使用可能)Document.requestStorageAccess()
また、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
が使用されている場合は、拒否され、例外が発生します。
不正使用を防ぐため、このブラウザ プロンプトはユーザーの操作後にのみ表示されます。そのため、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 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 が使用されます。
特定の状況では、ブラウザによってプロンプトがスキップされ、権限が自動的に付与されることがあります。
- プロンプトの承認後、過去 30 日間にページと iframe が使用されているかどうか。
- 埋め込まれた iframe が関連ウェブサイト セットの一部である場合。
- ストレージ アクセスの信頼シグナルとして FedCM が使用されている場合。
- Firefox では、既知のウェブサイト(最上位レベルで操作したウェブサイト)でも、最初の 5 回の試行ではプロンプトがスキップされます。
また、特定の状況では、プロンプトを表示せずにメソッドが自動的に拒否される場合があります。
- ユーザーが、iframe ではなく最上位ドキュメントとして iframe を所有するサイトを以前に訪問して操作したことがない。つまり、Storage Access API は、ユーザーが以前にファーストパーティのコンテキストでアクセスした埋め込みサイトにのみ有効です。
requestStorageAccess()
メソッドが、操作後のメッセージの事前承認なしで、ユーザー操作イベントの外部で呼び出された。
初回使用時にはユーザーにプロンプトが表示されますが、Chrome と Firefox では、それ以降のアクセスではプロンプトが表示されず、ユーザー操作も必要ありません。requestStorageAccess()
Safari では、常にユーザー操作が必要です。
Cookie とストレージへのアクセスはプロンプトやユーザー操作なしで許可される可能性があるため、ページの読み込み時に requestStorageAccess()
を呼び出すことで、これをサポートするブラウザ(Chrome と Firefox)でユーザー操作の前にパーティショニングされていない Cookie またはストレージへのアクセスを取得することが可能です。これにより、ユーザーが iframe を操作する前でも、パーティショニングされていない Cookie とストレージにすぐにアクセスして、より充実したエクスペリエンスを提供できる可能性があります。ユーザー操作を待つよりも、状況によってはユーザー エクスペリエンスが向上する場合があります。
連邦通信委員会(FCC)が SAA の信頼シグナルとして
FedCM(Federated Credential Management)は、サードパーティ Cookie やナビゲーション リダイレクトに依存しない、ID 連携サービス(「~でログイン」など)へのプライバシーを保護したアプローチです。
ユーザーが、FedCM を使用してサードパーティの ID プロバイダ(IdP)の埋め込みコンテンツを含むリレーショニング パーティ(RP)にログインすると、埋め込まれた IdP コンテンツは、独自の最上位のパーティショニングされていない Cookie へのストレージ アクセスを自動的に取得できます。FedCM で自動ストレージ アクセスを有効にするには、次の条件を満たす必要があります。
- FedCM 認証(ユーザーのログイン状態)が有効である必要があります。
- RP が
identity-credentials-get
権限を設定してオプトインしている(例:
<iframe src="https://idp.example" allow="identity-credentials-get"></iframe>
たとえば、idp.example
iframe が rp.example
に埋め込まれています。ユーザーが FedCM でログインすると、idp.example
iframe は独自のトップレベル Cookie のストレージ アクセスをリクエストできます。
rp.example
は FedCM を呼び出して、ID プロバイダ idp.example
でユーザーをログインさせます。
// The user will be asked to grant FedCM permission.
const cred = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/fedcm.json',
clientId: '123',
}],
},
});
ユーザーがログインすると、RP が 権限ポリシーで明示的に許可している限り、IdP は idp.example
iframe 内から requestStorageAccess()
を呼び出すことができます。埋め込みには、ユーザーによる有効化や別の権限プロンプトの必要なしに、独自のトップレベル クッキーへのストレージ アクセスが自動的に付与されます。
// Make this call within the embedded IdP iframe:
// No user gesture is needed, and the storage access will be auto-granted.
await document.requestStorageAccess();
// This returns `true`.
const hasAccess = await document.hasStorageAccess();
この権限は、ユーザーが FedCM にログインしている限り自動的に付与されます。認証が無効になると、標準の SAA 要件が適用され、ストレージへのアクセスが許可されます。
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 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
が必要です。 allow-scripts
は、JavaScript を使用して API を呼び出すことを許可するために必要です。allow-same-origin
は、同じオリジンの Cookie やその他のストレージへのアクセスを許可するために必要です。
次に例を示します。
<iframe sandbox="allow-storage-access-by-user-activation
allow-scripts
allow-same-origin"
src="..."></iframe>
Cookie の要件
Chrome の Storage Access API でアクセスするには、クロスサイト Cookie に次の 2 つの属性を設定する必要があります。
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()
メソッド
requestStorageAccessFor()
メソッドは requestStorageAccess()
と同様の方法で動作しますが、最上位リソースに対して動作します。関連ウェブサイト セット内のサイトにのみ使用でき、サードパーティ Cookie への一般的なアクセス権を付与しないようにします。
requestStorageAccessFor()
の使用方法について詳しくは、関連ウェブサイト セット: デベロッパー ガイドをご覧ください。
top-level-storage-access
権限クエリ
対応ブラウザ
storage-access
権限と同様に、requestStorageAccessFor()
へのアクセスを許可できるかどうかを確認する top-level-storage-access
権限があります。
Storage Access API を RWS で使用する場合の違いは何ですか?
Storage Access API で関連ウェブサイト セットを使用すると、次の表に示す特定の追加機能が利用可能になります。
RWS なし | RWS あり | |
---|---|---|
ストレージへのアクセス リクエストを開始するにはユーザー操作が必要 | ||
アクセスを許可する前に、ユーザーがリクエストされたストレージ オリジンにトップレベル コンテキストでアクセスすることを要求している | ||
初回ユーザーのプロンプトをスキップできる | ||
requestStorageAccess : アクセスがすでに付与されている場合は呼び出す必要はありません |
||
関連ウェブサイト サイトで他のドメインへのアクセスを自動的に許可する | ||
最上位ページへのアクセスに requestStorageAccessFor をサポート |
デモ: 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/
このデモを利用するには、Chrome 125 以降で test-third-party-cookie-phaseout フラグを有効にする必要があります。
リソース
- サードパーティ Cookie へのアクセスを提供する仕様を確認するか、問題を報告してください。
- パーティショニングされていないストレージ アクセスを提供する仕様を読むか、問題を報告してください。
- API のドキュメントとガイド。
- 関連ウェブサイトセットで Storage Access API を使用する方法に関する Chrome のドキュメント