Наборы связанных веб-сайтов (RWS) — это механизм веб-платформы, помогающий браузерам анализировать взаимосвязи между наборами доменов. Это позволяет браузерам принимать ключевые решения о включении определённых функций сайта (например, разрешать ли доступ к межсайтовым cookie-файлам) и предоставлять эту информацию пользователям.
Многие сайты используют несколько доменов для обслуживания одного и того же пользователя. Организациям может потребоваться использовать разные домены верхнего уровня для различных целей, например, домены для отдельных стран или служебные домены для размещения изображений или видео. Наборы связанных веб-сайтов позволяют сайтам обмениваться данными между доменами с помощью специальных настроек.
Что такое набор связанных веб-сайтов?
На высоком уровне набор связанных веб-сайтов представляет собой набор доменов, для которого существует один «основной набор» и потенциально несколько «членов набора».
В следующем примере primary перечисляет основной домен, а associatedSites перечисляет домены, которые соответствуют требованиям связанного подмножества .
{
"primary": "https://primary.com",
"associatedSites": ["https://associate1.com", "https://associate2.com", "https://associate3.com"]
}
Список связанных наборов веб-сайтов представлен в общедоступном JSON-файле, размещённом на GitHub . Это канонический источник всех утверждённых наборов. Браузеры используют этот файл для определения принадлежности сайтов к одному и тому же связанному набору веб-сайтов.
Создать набор с этим доменом могут только пользователи, обладающие административным контролем над ним. Заявители обязаны указать связь между каждым «участником набора» и его «основным участником набора». Участники набора могут включать в себя домены различных типов и должны быть частью подмножества, основанного на варианте использования .
Если ваше приложение зависит от доступа к межсайтовым cookie-файлам (также называемым сторонними cookie-файлами) на разных сайтах из одного набора связанных веб-сайтов, вы можете использовать API Storage Access (SAA) и API requestStorageAccessFor для запроса доступа к этим cookie-файлам. В зависимости от подмножества, к которому принадлежит каждый сайт, браузер может обрабатывать запрос по-разному.
Чтобы узнать больше о процессе и требованиях к подаче комплектов, ознакомьтесь с правилами подачи . Поданные комплекты пройдут различные технические проверки для подтверждения их достоверности.
Связанные варианты использования наборов веб-сайтов
Наборы связанных веб-сайтов хорошо подходят для случаев, когда организации требуется форма общей идентификации для разных сайтов верхнего уровня.
Некоторые варианты использования наборов связанных веб-сайтов:
- Настройка по странам . Использование локализованных сайтов с опорой на общую инфраструктуру (example.co.uk может использовать службу, размещенную на example.ca).
- Интеграция доменов услуг . Использование доменов услуг, с которыми пользователи никогда не взаимодействуют напрямую, но которые предоставляют услуги на сайтах той же организации (example-cdn.com).
- Разделение пользовательского контента . Доступ к данным на разных доменах, отделяющий загруженный пользователями контент от остального контента сайта в целях безопасности, при этом домен, находящийся в изолированной среде, может получить доступ к файлам cookie аутентификации (и другим файлам). Если вы размещаете неактивный загруженный пользователями контент, вы также можете безопасно разместить его на том же домене, следуя рекомендациям .
- Встроенный аутентифицированный контент . Поддержка встроенного контента из аффилированных ресурсов (видео, документы или ресурсы, доступные только пользователю, вошедшему в систему на сайте верхнего уровня).
- Вход . Поддержка входа на аффилированных ресурсах. API FedCM также может быть полезен в некоторых случаях.
- Аналитика . Внедрение аналитики и измерение действий пользователей на связанных объектах для повышения качества услуг.
Подробности интеграции связанных наборов веб-сайтов
API доступа к хранилищу
Интерфейс 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
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
Файлы cookie должны указывать атрибуты SameSite=None и Secure , поскольку rSA предоставляет доступ только к тем файлам cookie, которые уже отмечены для использования в межсайтовом контексте .
Файлы cookie с атрибутом SameSite=Lax , SameSite SameSite=Strict или без него предназначены только для использования основной стороной и никогда не будут передаваться в межсайтовом контексте независимо от 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.
Сайты верхнего уровня, запрашивающие доступ к cookie-файлам от имени сайтов с разными источниками

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 с локальным набором связанных веб-сайтов
Чтобы запустить 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 . В новой ветке внесите изменения в файл related_website_sets.JSON , чтобы отразить ваш набор. Чтобы убедиться, что ваш набор имеет правильное форматирование и структуру JSON, вы можете использовать JSON Generator Tool .
3. Убедитесь, что ваш RWS соответствует техническим требованиям.
Обеспечить соблюдение требований к формированию и проверке набора .
4. Протестируйте RWS локально
Прежде чем создавать запрос на извлечение (PR) для отправки своего набора, протестируйте его локально, чтобы убедиться, что он проходит все необходимые проверки.
5. Отправьте свой RWS
Отправьте список связанных веб-сайтов, создав запрос на изменение (PR) в файле related_website_sets.JSON , где Chrome размещает канонический список связанных веб-сайтов. (Для создания запросов на изменение (PR) требуется учётная запись GitHub, а перед внесением изменений в список вам потребуется подписать лицензионное соглашение участника (CLA) .)
После создания PR выполняется ряд проверок, чтобы убедиться в соблюдении требований шага 3, например, в том, что вы подписали CLA и что файл .well-known действителен.
В случае успешного выполнения PR-запрос будет указывать на прохождение проверок. Одобренные PR-запросы будут вручную объединяться партиями в канонический список связанных веб-сайтов раз в неделю (по вторникам в 12:00 по восточному времени). Если какая-либо из проверок не пройдена, автор запроса будет уведомлен об этом через сообщение об ошибке PR-запроса на GitHub. Автор может исправить ошибки и обновить PR-запрос. Обратите внимание:
- Если PR не будет выполнен, сообщение об ошибке предоставит дополнительную информацию о причине, по которой отправка могла быть не выполнена. ( пример ).
- Все технические проверки, регулирующие отправку наборов, проводятся на GitHub, и, следовательно, все ошибки отправки, возникшие в результате технических проверок, будут видны на GitHub.
Корпоративные политики
В Chrome реализованы две политики для удовлетворения потребностей корпоративных пользователей:
- Системы, которые не могут интегрироваться с наборами связанных веб-сайтов, могут отключить функцию «Наборы связанных веб-сайтов» во всех корпоративных экземплярах Chrome с помощью политики
RelatedWebsiteSetsEnabled.- В некоторых корпоративных системах есть сайты, предназначенные только для внутреннего использования (например, интранет), с регистрируемыми доменами, отличными от доменов в их наборе связанных веб-сайтов. Если необходимо рассматривать эти сайты как часть набора связанных веб-сайтов, не публикуя их (поскольку домены могут быть конфиденциальными), можно дополнить или переопределить общедоступный список наборов связанных веб-сайтов с помощью политики
RelatedWebsiteSetsOverrides.
- В некоторых корпоративных системах есть сайты, предназначенные только для внутреннего использования (например, интранет), с регистрируемыми доменами, отличными от доменов в их наборе связанных веб-сайтов. Если необходимо рассматривать эти сайты как часть набора связанных веб-сайтов, не публикуя их (поскольку домены могут быть конфиденциальными), можно дополнить или переопределить общедоступный список наборов связанных веб-сайтов с помощью политики
Chrome разрешает любое пересечение общедоступных и корпоративных наборов одним из двух способов в зависимости от того, указаны ли replacements или 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]} |
| Публичные и корпоративные наборы объединены. | |
| Результирующий набор: | {primary: C, associated: [A, B, D, E]} |
Устранение неполадок в связанных наборах веб-сайтов
«Подсказка пользователя» и «жест пользователя»
«Запрос пользователя» и «жест пользователя» — это разные вещи. Chrome не будет запрашивать разрешение у пользователей для сайтов, входящих в тот же набор связанных веб-сайтов, но Chrome по-прежнему требует, чтобы пользователь взаимодействовал со страницей. Перед предоставлением разрешения Chrome требует выполнения жеста пользователя , также называемого «взаимодействием пользователя» или «активацией пользователя». Это связано с тем, что использование API доступа к хранилищу вне контекста набора связанных веб-сайтов (а именно requestStorageAccess() ) также требует выполнения жеста пользователя в соответствии с принципами проектирования веб-платформ .
Доступ к файлам cookie или хранилищу других сайтов
Related Website Sets не объединяет хранилище для разных сайтов: он просто позволяет упростить (без подсказок) вызовы requestStorageAccess() . Related Website Sets только снижает неудобства для пользователя при использовании API доступа к хранилищу, но не диктует, что делать после восстановления доступа. Если A и B — разные сайты в одном Related Website Set, и A встраивает B, то B может вызвать requestStorageAccess() и получить доступ к основному хранилищу без запроса пользователя. Related Website Sets не выполняет никаких межсайтовых коммуникаций. Например, настройка Related Website Set не приведет к тому, что файлы cookie, принадлежащие B, начнут отправляться в A. Если вы хотите поделиться этими данными, вам придется поделиться ими самостоятельно, например, отправив window.postMessage из iframe B во фрейм A.
Неразделенный доступ к cookie-файлам по умолчанию
Набор связанных веб-сайтов не допускает неявного неразделённого доступа к файлам cookie без вызова API. Межсайтовые файлы cookie по умолчанию недоступны в наборе; набор связанных веб-сайтов позволяет сайтам в наборе просто пропустить запрос на разрешение Storage Access API . Для доступа к своим файлам cookie элемент iframe должен вызвать метод document.requestStorageAccess() , или страница верхнего уровня может вызвать метод document.requestStorageAccessFor() .
Поделитесь отзывом
Отправка набора на GitHub и работа с API Storage Access и API requestStorageAccessFor — это возможности поделиться своим опытом в отношении процесса и любых проблем, с которыми вы сталкиваетесь.
Чтобы присоединиться к обсуждению связанных наборов веб-сайтов:
- Подпишитесь на публичную рассылку Related Website Sets.
- Поднимайте вопросы и следите за обсуждениями в репозитории Related Website Sets GitHub .