Похожие наборы веб-сайтов: руководство для разработчиков

Наборы связанных веб-сайтов (RWS) — это механизм веб-платформы, который помогает браузерам понимать отношения между набором доменов. Это позволяет браузерам принимать ключевые решения по включению определенных функций сайта (например, разрешить ли доступ к межсайтовым файлам cookie) и предоставлять эту информацию пользователям.

Поскольку Chrome отказывается от сторонних файлов cookie, его цель — поддерживать ключевые варианты использования в Интернете, одновременно улучшая конфиденциальность пользователей. Например, многие сайты используют несколько доменов для обслуживания одного пользователя. Организации могут захотеть поддерживать разные домены верхнего уровня для нескольких случаев использования, например домены для конкретной страны или домены служб для размещения изображений или видео. Связанные наборы веб-сайтов позволяют сайтам обмениваться данными между доменами с помощью специальных элементов управления.

На высоком уровне набор связанных веб-сайтов представляет собой набор доменов, для которых существует один «основной набор» и потенциально несколько «членов набора».

В следующем примере primary указан основной домен, а в associatedSites перечислены домены, соответствующие требованиям связанного подмножества .

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

Канонический список наборов связанных веб-сайтов — это общедоступный список в формате файла JSON, размещенный в репозитории наборов связанных веб-сайтов GitHub , который служит источником достоверной информации для всех наборов. Chrome использует этот файл, чтобы применить его к своему поведению.

Только те, кто имеет административный контроль над доменом, могут создать набор с этим доменом. Отправители обязаны объявить связь между каждым «членом набора» и его «основным набором». Члены набора могут включать в себя диапазон различных типов доменов и должны быть частью подмножества в зависимости от варианта использования .

Если ваше приложение зависит от доступа к межсайтовым файлам cookie (также называемым сторонними файлами cookie) на сайтах одного и того же набора связанных веб-сайтов, вы можете использовать API доступа к хранилищу (SAA) и API requestStorageAccessFor, чтобы запросить доступ к этим файлам cookie. В зависимости от подмножества, частью которого является каждый сайт, браузер может обрабатывать запрос по-разному.

Чтобы узнать больше о процессе и требованиях к отправке наборов, ознакомьтесь с правилами подачи . Отправленные наборы пройдут различные технические проверки для проверки представленных материалов.

Наборы связанных веб-сайтов хорошо подходят для случаев, когда организации требуется форма общего удостоверения на разных сайтах верхнего уровня.

Вот некоторые варианты использования наборов связанных веб-сайтов:

  • Настройка страны . Использование локализованных сайтов при использовании общей инфраструктуры (example.co.uk может полагаться на службу, размещенную на example.ca).
  • Интеграция сервисного домена . Использование доменов служб, с которыми пользователи никогда не взаимодействуют напрямую, но предоставляют услуги на сайтах одной и той же организации (example-cdn.com).
  • Разделение пользовательского контента . Доступ к данным в разных доменах, которые отделяют загружаемый пользователем контент от другого контента сайта по соображениям безопасности, одновременно разрешая изолированному домену доступ к аутентификационным (и другим) файлам cookie. Если вы размещаете неактивный контент, загруженный пользователями, вы также можете безопасно разместить его в том же домене, следуя рекомендациям .
  • Встроенный аутентифицированный контент . Поддержка встроенного контента со всех дочерних ресурсов (видео, документы или ресурсы, доступ к которым ограничен для пользователя, вошедшего в систему на сайте верхнего уровня).
  • Войти . Поддержка входа на аффилированные ресурсы. API FedCM также может подойти для некоторых случаев использования.
  • Аналитика . Развертывание аналитики и измерение пути пользователей на дочерних объектах для повышения качества услуг.

API доступа к хранилищу

Поддержка браузера

  • Хром: 119.
  • Край: 85.
  • Фаерфокс: 65.
  • Сафари: 11.1.

Источник

API доступа к хранилищу (SAA) предоставляет встроенному контенту из разных источников доступ к хранилищу, к которому обычно он имеет доступ только в собственном контексте.

Встроенные ресурсы могут использовать методы SAA, чтобы проверить, есть ли у них в данный момент доступ к хранилищу, и запросить доступ у пользовательского агента.

Если сторонние файлы cookie заблокированы, но включены наборы связанных веб-сайтов (RWS), Chrome автоматически предоставляет разрешение во внутриконтекстах RWS и в противном случае отображает запрос пользователю. («Контекст внутри RWS» — это контекст, например iframe, встроенный сайт которого и сайт верхнего уровня находятся в одном RWS.)

Проверить и запросить доступ к хранилищу

Чтобы проверить, есть ли у них в данный момент доступ к хранилищу, встроенные сайты могут использовать метод Document.hasStorageAccess() .

Метод возвращает обещание, которое разрешается с помощью логического значения, указывающего, имеет ли документ уже доступ к своим файлам cookie или нет. Обещание также возвращает true, если iframe имеет то же происхождение, что и верхний кадр.

Чтобы запросить доступ к файлам cookie в межсайтовом контексте, встроенные сайты могут использовать Document.requestStorageAccess() (rSA).

API requestStorageAccess() предназначен для вызова из iframe. Этот iframe должен только что получить взаимодействие с пользователем ( жест пользователя , который требуется для всех браузеров), но Chrome дополнительно требует, чтобы в какой-то момент за последние 30 дней пользователь посетил сайт, которому принадлежит этот iframe, и взаимодействовал с ним. именно этот сайт — как документ верхнего уровня, а не в iframe.

requestStorageAccess() возвращает обещание, которое разрешает, был ли предоставлен доступ к хранилищу. Обещание отклоняется с указанием причины, если в доступе по какой-либо причине было отказано.

RequestStorageAccessFor в Chrome

Поддержка браузера

  • Хром: 119.
  • Край: 119.
  • Firefox: не поддерживается.
  • Сафари: не поддерживается.

Источник

API доступа к хранилищу позволяет встроенным сайтам запрашивать доступ к хранилищу только из элементов <iframe> , получивших взаимодействие с пользователем.

Это создает проблемы при внедрении API доступа к хранилищу для сайтов верхнего уровня, которые используют межсайтовые изображения или теги скриптов, требующие файлов cookie.

Чтобы решить эту проблему, Chrome реализовал возможность для сайтов верхнего уровня запрашивать доступ к хранилищу от имени определенных источников с помощью Document.requestStorageAccessFor() (rSAFor).

 document.requestStorageAccessFor('https://target.site')

API requestStorageAccessFor() предназначен для вызова из документа верхнего уровня. Этот документ также должен был только что получить взаимодействие с пользователем. Но в отличие от requestStorageAccess() , Chrome не проверяет взаимодействие в документе верхнего уровня в течение последних 30 дней, поскольку пользователь уже находится на странице.

Проверьте права доступа к хранилищу

Доступ к некоторым функциям браузера, таким как камера или геолокация, основан на разрешениях, предоставленных пользователем. 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, которые уже помечены для использования в межсайтовом контексте .

Файлы cookie с SameSite=Lax , SameSite=Strict или без атрибута SameSite предназначены только для собственного использования и никогда не будут использоваться в межсайтовом контексте независимо от rSA.

Безопасность

Для rSAFor запросы подресурсов требуют заголовков Cross-Origin Resource Sharing (CORS) или атрибута crossorigin ресурсов, что обеспечивает явное согласие.

Примеры реализации

Запросить доступ к хранилищу из встроенного iframe из разных источников.

Диаграмма, показывающая встроенный сайт на сайте верхнего уровня.
Использование requestStorageAccess() во вставке на другом сайте.

Проверьте, есть ли у вас доступ к хранилищу

Чтобы проверить, есть ли у вас доступ к хранилищу, используйте document.hasStorageAccess() .

Если обещание принимает истинное значение, вы можете получить доступ к хранилищу в межсайтовом контексте. Если он принимает ложное решение, вам необходимо запросить доступ к хранилищу.

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() межсайтовые запросы будут включать файлы cookie, если они включают CORS или атрибут crossorigin, поэтому сайтам может потребоваться подождать, прежде чем запускать запрос.

Запросы должны использовать 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 или более поздней версии, запускаемый из командной строки, и включите флаг Chrome test-third-party-cookie-phaseout .

Включите флаг Chrome

Чтобы включить необходимый флаг Chrome, перейдите по chrome://flags#test-third-party-cookie-phaseout из адресной строки и измените флаг на Enabled . Обязательно перезапустите браузер после изменения флагов.

Чтобы запустить Chrome с локально объявленным набором связанных веб-сайтов, создайте объект JSON, содержащий URL-адреса, являющиеся членами набора, и передайте его в --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/

Пример

Чтобы включить наборы связанных веб-сайтов локально, вам необходимо включить test-third-party-cookie-phaseout в chrome://flags и запустить Chrome из командной строки с флагом --use-related-website-set с JSON. объект, содержащий URL-адреса, являющиеся членами набора.

--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 . В новой ветке внесите изменения в файл linked_website_sets.JSON , чтобы отразить ваш набор. Чтобы убедиться, что ваш набор имеет правильное форматирование и структуру JSON, вы можете использовать инструмент JSON Generator Tool .

3. Убедитесь, что ваш RWS соответствует техническим требованиям.

Убедитесь, что установлены требования к формированию набора и требования к проверке набора .

4. Проверьте свой RWS локально

Прежде чем создавать запрос на включение (PR) для отправки вашего набора, протестируйте его локально, чтобы убедиться, что он проходит все необходимые проверки.

5. Отправьте свой RWS

Отправьте набор связанных веб-сайтов, создав PR для файла linked_website_sets.JSON , в котором Chrome размещает канонический список набора связанных веб-сайтов. (Для создания PR требуется учетная запись GitHub, и вам нужно будет подписать Лицензионное соглашение участника (CLA), прежде чем вы сможете внести свой вклад в список.)

После создания PR выполняется ряд проверок, чтобы убедиться в выполнении требований шага 3, например, убедиться в том, что вы подписали CLA и что файл .well-known действителен.

В случае успеха PR укажет, что проверки пройдены. Утвержденные запросы на запросы будут вручную объединяться партиями в канонический набор связанных веб-сайтов один раз в неделю (по вторникам в 12:00 по восточному времени). Если какая-либо из проверок не пройдена, отправитель будет уведомлен об ошибке PR на GitHub. Отправитель может исправить ошибки и обновить PR, при этом имейте в виду, что:

  • Если запрос запроса на отправку не пройден, в сообщении об ошибке будет предоставлена ​​дополнительная информация о том, почему отправка могла не удаться. ( пример ).
  • Все технические проверки, регулирующие отправку наборов, проводятся на GitHub, и, следовательно, все ошибки отправки, возникшие в результате технических проверок, можно будет просмотреть на GitHub.

Корпоративная политика

В Chrome действуют две политики для удовлетворения потребностей корпоративных пользователей:

  • Системы, которые не могут интегрироваться с наборами связанных веб-сайтов, могут отключить функцию наборов связанных веб-сайтов во всех корпоративных экземплярах Chrome с помощью политики RelatedWebsiteSetsEnabled .
  • Некоторые корпоративные системы имеют сайты только для внутреннего использования (например, интрасеть) с регистрируемыми доменами, которые отличаются от доменов в их наборе связанных веб-сайтов. Если им необходимо рассматривать эти сайты как часть своего набора связанных веб-сайтов, не раскрывая их публично (поскольку домены могут быть конфиденциальными), они могут дополнить или переопределить свой общедоступный список наборов связанных веб-сайтов с помощью политики RelatedWebsiteSetsOverrides .

Chrome разрешает любое пересечение общедоступного и корпоративного наборов одним из двух способов, в зависимости от того, указаны ли replacemements или additions .

Например, для общедоступного набора {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 требует жеста пользователя , также называемого «взаимодействием с пользователем» или «активацией пользователя». Это связано с тем, что использование API доступа к хранилищу вне контекста набора связанных веб-сайтов (а именно requestStorageAccess() ) также требует жеста пользователя из-за принципов проектирования веб-платформы .

Доступ к файлам cookie или хранилищу других сайтов

Связанные наборы веб-сайтов не объединяют хранилище для разных сайтов: они просто позволяют выполнять более простые (без подсказок) вызовы requestStorageAccess() . Связанные наборы веб-сайтов только уменьшают трудности пользователя при использовании API доступа к хранилищу, но не диктуют, что делать после восстановления доступа. Если A и B — разные сайты в одном наборе связанных веб-сайтов и A встраивает B, B может вызвать requestStorageAccess() и получить доступ к собственному хранилищу без запроса пользователя. Связанные наборы веб-сайтов не обеспечивают межсайтового взаимодействия. Например, настройка набора связанных веб-сайтов не приведет к тому, что файлы cookie, принадлежащие B, начнут отправляться на A. Если вы хотите поделиться этими данными, вам придется поделиться ими самостоятельно, например, отправив window.postMessage от iframe B в кадр A.

Связанные наборы веб-сайтов не допускают неявного доступа к неразделенным файлам cookie без вызова какого-либо API. Межсайтовые файлы cookie по умолчанию недоступны в наборе; Связанные наборы веб-сайтов просто позволяют сайтам в наборе пропускать запрос разрешения API доступа к хранилищу . iframe должен вызвать document.requestStorageAccess() если он хочет получить доступ к своим файлам cookie, или страница верхнего уровня может вызвать document.requestStorageAccessFor() .

Поделиться отзывом

Отправка набора на GitHub и работа с API доступа к хранилищу и API requestStorageAccessFor — это возможность поделиться своим опытом работы с процессом и любыми проблемами, с которыми вы столкнулись.

Чтобы присоединиться к обсуждению связанных наборов веб-сайтов: