関連ウェブサイト セット: デベロッパー ガイド

関連ウェブサイト セット(RWS)は、ブラウザがドメインのコレクション間の関係を理解するのに役立つウェブ プラットフォームのメカニズムです。これにより、ブラウザは特定のサイト機能(クロスサイト Cookie へのアクセスを許可するかどうかなど)を有効にするための重要な決定を行い、この情報をユーザーに提示できます。

多くのサイトでは、複数のドメインを使用して単一のユーザー エクスペリエンスを提供しています。組織は、国固有のドメインや、画像や動画をホストするサービス ドメインなど、複数のユースケースで異なるトップレベル ドメインを維持することがあります。関連ウェブサイト セットを使用すると、サイトは特定の制御でドメイン間でデータを共有できます。

関連ウェブサイト セットは、1 つの「セット プライマリ」と複数の「セット メンバー」で構成されるドメインの集合です。

次の例では、primary にプライマリ ドメインが一覧表示され、associatedSites関連付けられたサブセットの要件を満たすドメインが一覧表示されます。

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

関連ウェブサイト セットは、GitHub でホストされている一般公開の JSON ファイルに記載されています。これは、承認されたすべてのセットの正規のソースです。ブラウザはこのファイルを使用して、サイトが同じ関連ウェブサイト セットに属しているかどうかを判断します。

ドメインの管理権限を持つユーザーのみが、そのドメインを含むセットを作成できます。送信者は、各「セットメンバー」と「セットプライマリ」の関係を宣言する必要があります。セットメンバーにはさまざまなドメインタイプを含めることができ、ユースケースに基づくサブセットの一部である必要があります。

アプリケーションが同じ関連ウェブサイト セット内のサイト間でクロスサイト Cookie(サードパーティ Cookie とも呼ばれます)へのアクセスに依存している場合は、Storage Access API(SAA)requestStorageAccessFor API を使用して、これらの Cookie へのアクセスをリクエストできます。各サイトが属するサブセットに応じて、ブラウザはリクエストを異なる方法で処理する場合があります。

セットの登録プロセスと要件について詳しくは、登録ガイドラインをご覧ください。送信されたセットは、送信内容を検証するためにさまざまな技術チェックを受けます。

関連ウェブサイト セットは、組織がさまざまなトップレベル サイトで共有 ID を必要とする場合に適しています。

関連ウェブサイト セットのユースケースには、次のようなものがあります。

  • 国別のカスタマイズ。ローカライズされたサイトを活用しながら、共有インフラストラクチャに依存している(example.co.uk が example.ca でホストされているサービスに依存しているなど)。
  • サービス ドメインの統合。ユーザーが直接操作することはないが、同じ組織のサイト全体でサービスを提供するサービス ドメイン(example-cdn.com)を活用する。
  • ユーザー コンテンツの分離。セキュリティ上の理由からユーザーがアップロードしたコンテンツを他のサイト コンテンツから分離している異なるドメインのデータにアクセスしながら、サンドボックス化されたドメインが認証(およびその他の)Cookie にアクセスできるようにします。アップロードされたコンテンツのうち、アクティブでないものを配信している場合は、ベスト プラクティスに沿って、同じドメインで安全にホストできる可能性があります。
    • 認証済みコンテンツの埋め込み。関連付けられたプロパティ全体からの埋め込みコンテンツ(動画、ドキュメント、最上位サイトにログインしたユーザーに限定されたリソース)のサポート。
  • ログイン。関連付けられたプロパティ全体でログインをサポートします。FedCM API も、一部のユースケースに適している可能性があります。
  • 分析。関連するプロパティ全体でユーザー ジャーニーの分析と測定をデプロイし、サービスの品質を向上させるため。

関連ウェブサイト セットの統合の詳細

Storage Access 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 にすでにアクセスできるかどうかを示すブール値で解決される Promise を返します。iframe がトップフレームと同じオリジンの場合も、この Promise は true を返します。

埋め込みサイトがクロスサイト コンテキストで Cookie へのアクセスをリクエストするには、Document.requestStorageAccess()(rSA)を使用します。

requestStorageAccess() API は、iframe 内から呼び出すことを想定しています。その iframe はユーザー操作(すべてのブラウザで必須のユーザー ジェスチャー)を直前に受け取っている必要がありますが、Chrome ではさらに、過去 30 日間のいずれかの時点で、ユーザーがその iframe を所有するサイトにアクセスし、そのサイト(iframe ではなく最上位ドキュメントとして)を操作していることも必要です。

requestStorageAccess() は、ストレージへのアクセスが許可された場合に解決される Promise を返します。なんらかの理由でアクセスが拒否された場合、理由を挙げて Promise が拒否されます。

Chrome の requestStorageAccessFor

Browser Support

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

Source

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 を使用してトップレベル ドキュメントによって付与された権限のみがチェックされます。

権限を自動的に付与できるか、ユーザー操作が必要かによって、prompt または granted を返します。

フレームモデルごと

rSA 権限はフレームごとに適用されます。rSA 権限と rSAFor 権限は別々の権限として扱われます。

新しいフレームはそれぞれ個別にストレージ アクセスをリクエストする必要があり、アクセスは自動的に許可されます。最初の要求のみにユーザー操作が必要で、ナビゲーションやサブリソースなど、iframe によって開始される後続の要求は、最初の要求によってブラウジング セッションに付与されるため、ユーザー操作を待つ必要はありません。

iframe を更新、再読み込み、または再作成すると、再度アクセス権をリクエストする必要があります。

Cookie は SameSite=None 属性と Secure 属性の両方を rSA として指定する必要があります。これにより、クロスサイト コンテキストでの使用がすでにマークされている Cookie へのアクセスが提供されます

SameSite=LaxSameSite=Strict、または SameSite 属性のない Cookie はファーストパーティ専用であり、rSA に関係なく、クロスサイト コンテキストで共有されることはありません。

セキュリティ

rSAFor の場合、サブリソース リクエストには、クロスオリジン リソース シェアリング(CORS)ヘッダーまたはリソースの crossorigin 属性が必要です。これにより、明示的なオプトインが保証されます。

実装の例

埋め込みクロスオリジン iframe からストレージへのアクセスをリクエストする

top-level.site に埋め込まれたサイトを示す図
別のサイトの埋め込みで requestStorageAccess() を使用する。

ストレージへのアクセス権があるかどうかを確認する

ストレージへのアクセス権がすでに付与されているかどうかを確認するには、document.hasStorageAccess() を使用します。

Promise が 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 呼び出しなしでこれらのリクエストで送信されます。

クロスオリジン サイトの代わりに Cookie へのアクセスをリクエストするトップレベル サイト

最上位サイトで 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 を起動する

ローカルで宣言された関連ウェブサイト セットを使用して Chrome を起動するには、セットのメンバーである URL を含む 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://flagstest-third-party-cookie-phaseout を有効にし、セットのメンバーである URL を含む JSON オブジェクトを指定した --use-related-website-set フラグを使用して、コマンドラインから 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. RWS を特定する

関連ウェブサイト セットの一部となるセットのプライマリセットのメンバーを含む、関連するドメインを特定します。また、各セットメンバーが属するサブセット タイプも特定します。

2. RWS 申請を作成する

GitHub リポジトリのローカルコピー(クローンまたはフォーク)を作成します。新しいブランチで、セットを反映するように related_website_sets.JSON ファイルに変更を加えます。セットの JSON 形式と構造が正しいことを確認するには、JSON ジェネレータ ツールを使用します。

3. RWS が技術要件を満たしていることを確認する

セットの作成要件セットの検証要件が満たされていることを確認します。

4. RWS をローカルでテストする

セットを送信するプルリクエスト(PR)を作成する前に、送信内容をローカルでテストして、必要なチェックをすべてパスすることを確認してください。

5. RWS を送信する

Chrome が正規の関連ウェブサイト セットのリストをホストしている related_website_sets.JSON ファイルに PR を作成して、関連ウェブサイト セットを送信します。(PR を作成するには GitHub アカウントが必要です。また、リストに投稿する前に投稿者ライセンス契約(CLA)に署名する必要があります)。

PR が作成されると、一連のチェックが完了し、CLA に署名したことや .well-known ファイルが有効であることなど、手順 3 の要件が満たされていることが確認されます。

成功すると、PR にチェックが合格したことが示されます。承認された PR は、週に 1 回(火曜日の正午(東部時間))、正規の関連ウェブサイト セット リストにバッチで手動でマージされます。いずれかのチェックに失敗した場合、GitHub で PR の失敗が通知されます。送信者はエラーを修正して PR を更新できます。その際、次の点に注意してください。

  • PR が失敗した場合、エラー メッセージに、送信が失敗した理由に関する追加情報が表示されます。()。
  • セットの提出を管理するすべての技術チェックは GitHub で実施されます。そのため、技術チェックの結果、提出が失敗した場合は、GitHub で確認できます。

エンタープライズ ポリシー

Chrome には、企業ユーザーのニーズを満たすための 2 つのポリシーが用意されています。

  • 関連ウェブサイト セットと統合できないシステムでは、RelatedWebsiteSetsEnabled ポリシーを使用して、Chrome のすべてのエンタープライズ インスタンスで関連ウェブサイト セット機能を無効にできます。
    • 一部のエンタープライズ システムには、関連ウェブサイト セットのドメインとは異なる登録可能なドメインを持つ内部専用サイト(イントラネットなど)があります。これらのサイトを一般公開せずに(ドメインが機密情報である可能性があるため)関連ウェブサイト セットの一部として扱う必要がある場合は、RelatedWebsiteSetsOverrides ポリシーを使用して、関連ウェブサイト セットの公開リストを拡張またはオーバーライドできます。

Chrome は、replacements または additions が指定されているかどうかに応じて、パブリック セットとエンタープライズ セットの交差を次の 2 つの方法のいずれかで解決します。

たとえば、一般公開セット {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]}
Public セットと Enterprise セットが統合されます。
結果セット: {primary: C, associated: [A, B, D, E]}

関連ウェブサイト セットのトラブルシューティング

「ユーザー プロンプト」と「ユーザー ジェスチャー」

「ユーザー プロンプト」と「ユーザー ジェスチャー」は異なります。Chrome では、同じ関連ウェブサイト セットに含まれるサイトに対して、ユーザーに権限のプロンプトが表示されることはありませんが、ユーザーがページを操作したことは Chrome で確認されます。Chrome では、権限を付与する前に、ユーザー操作(「ユーザー インタラクション」または「ユーザー アクティベーション」とも呼ばれます)が必要です。これは、関連ウェブサイト セットのコンテキスト外(つまり requestStorageAccess())で Storage Access API を使用する場合も、ウェブ プラットフォームの設計原則により、ユーザー操作が必要になるためです。

他のサイトの Cookie またはストレージにアクセスする

関連ウェブサイト セットは、異なるサイトのストレージを統合するものではなく、requestStorageAccess() 呼び出しをより簡単(プロンプトなし)に行えるようにするだけです。関連ウェブサイト セットは、Storage Access API の使用におけるユーザーの摩擦を軽減するだけで、アクセスが復元された後の動作を規定するものではありません。A と B が同じ関連ウェブサイト セット内の異なるサイトで、A が B を埋め込んでいる場合、B は requestStorageAccess() を呼び出して、ユーザーにプロンプトを表示せずにファーストパーティ ストレージにアクセスできます。関連ウェブサイト セットはクロスサイト通信を行いません。たとえば、関連ウェブサイト セットを設定しても、B に属する Cookie が A に送信されることはありません。そのデータを共有する場合は、B iframe から A フレームに window.postMessage を送信するなど、ご自身で共有する必要があります。

関連ウェブサイト セットでは、API を呼び出さずにパーティション化されていない Cookie に暗黙的にアクセスすることはできません。クロスサイト Cookie は、セット内でデフォルトでは利用できません。関連ウェブサイト セットは、セット内のサイトが Storage Access API の権限プロンプトをスキップできるようにするだけです。iframe が Cookie にアクセスする場合は document.requestStorageAccess() を呼び出す必要があります。トップレベル ページは document.requestStorageAccessFor() を呼び出すことができます。

フィードバックを共有

GitHub でセットを送信し、Storage Access API と requestStorageAccessFor API を使用することで、プロセスに関する経験や発生した問題を共有できます。

関連ウェブサイト セットに関するディスカッションに参加するには: