Powiązane zestawy witryn: przewodnik dla programistów

Zestawy powiązanych witryn to mechanizm platformy internetowej, który pomaga przeglądarkom zrozumieć relacje między zbiorem domen. Dzięki temu przeglądarki mogą podejmować kluczowe decyzje dotyczące włączania określonych funkcji witryny (np. zezwalania na dostęp do plików cookie w wielu witrynach) i prezentowania tych informacji użytkownikom.

Wiele witryn korzysta z wielu domen, aby zapewnić użytkownikom spójne wrażenia. Organizacje mogą chcieć utrzymywać różne domeny najwyższego poziomu na potrzeby różnych zastosowań, takich jak domeny dla poszczególnych krajów lub domeny usług do hostowania obrazów lub filmów. Zestawy powiązanych witryn umożliwiają witrynom udostępnianie danych w różnych domenach z użyciem określonych ustawień.

Ogólnie rzecz biorąc, zestaw powiązanych witryn to zbiór domen, w których przypadku istnieje jedna „witryna główna” i potencjalnie wiele „witryn członkowskich”.

W tym przykładzie primary to domena główna, a associatedSites to domeny, które spełniają wymagania powiązanego podzbioru.

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

Powiązane zestawy witryn są wymienione w publicznym pliku JSON hostowanym na GitHubie. Jest to źródło kanoniczne wszystkich zatwierdzonych zestawów. Przeglądarki używają tego pliku do określania, czy witryny należą do tego samego zestawu powiązanych witryn.

Tylko osoby z kontrolą administracyjną nad domeną mogą tworzyć zestawy z tą domeną. Zgłaszający muszą zadeklarować relację między każdym „elementem zbioru” a „elementem głównym zbioru”. Elementy zbioru mogą obejmować różne typy domen i muszą być częścią podzbioru na podstawie przypadku użycia.

Jeśli aplikacja wymaga dostępu do plików cookie w wielu witrynach (zwanych też plikami cookie innych firm) w ramach tego samego zestawu powiązanych witryn, możesz użyć interfejsu Storage Access API (SAA) i interfejsu requestStorageAccessFor API, aby poprosić o dostęp do tych plików cookie. W zależności od podzbioru, do którego należy dana witryna, przeglądarka może inaczej obsługiwać żądanie.

Aby dowiedzieć się więcej o procesie i wymaganiach dotyczących przesyłania zestawów, zapoznaj się z wytycznymi dotyczącymi przesyłania. Przesłane zestawy zostaną poddane różnym weryfikacjom technicznym w celu potwierdzenia ich poprawności.

Zestawy powiązanych witryn są dobrym rozwiązaniem w przypadku, gdy organizacja potrzebuje wspólnej tożsamości w różnych witrynach najwyższego poziomu.

Oto kilka przykładowych zastosowań zestawów powiązanych witryn:

  • Dostosowywanie kraju. Korzystanie z lokalizowanych witryn przy użyciu współdzielonej infrastruktury (example.co.uk może korzystać z usługi hostowanej przez example.ca).
  • Integracja z domeną usługi. Korzystanie z domen usług, z którymi użytkownicy nigdy nie wchodzą w bezpośrednią interakcję, ale które zapewniają usługi w ramach witryn tej samej organizacji (example-cdn.com).
  • oddzielenie treści użytkowników. Dostęp do danych w różnych domenach, które ze względów bezpieczeństwa oddzielają treści przesłane przez użytkowników od innych treści witryny, a jednocześnie umożliwiają domenie w piaskownicy dostęp do plików cookie uwierzytelniania (i innych). Jeśli wyświetlasz nieaktywne treści przesłane przez użytkowników, możesz je bezpiecznie hostować w tej samej domenie, stosując się do sprawdzonych metod.
    • Umieszczone treści uwierzytelnione. Obsługa treści umieszczonych w powiązanych usługach (filmy, dokumenty lub zasoby dostępne tylko dla zalogowanego użytkownika w witrynie najwyższego poziomu).
  • Logowanie. Obsługa logowania w powiązanych usługach. W niektórych przypadkach odpowiednia może być też FedCM API.
  • Analytics. wdrażanie analiz i pomiarów ścieżek użytkowników w usługach należących do firmy, aby poprawić jakość usług;

Szczegóły integracji zestawów powiązanych witryn

Interfejs Storage Access API

Browser Support

  • Chrome: 119.
  • Edge: 85.
  • Firefox: 65.
  • Safari: 11.1.

Source

Interfejs Storage Access API (SAA) umożliwia umieszczanym w innych domenach treściom dostęp do pamięci, do której normalnie mają dostęp tylko w kontekście własnych zasobów.

Zasoby umieszczone mogą używać metod SAA, aby sprawdzić, czy mają obecnie dostęp do pamięci masowej, oraz poprosić o dostęp do niej za pomocą agenta użytkownika.

Gdy pliki cookie innych firm są zablokowane, a zestawy powiązanych witryn są włączone, Chrome automatycznie przyznaje uprawnienia w kontekście zestawów powiązanych witryn, a w innych przypadkach wyświetla użytkownikowi prośbę. („Kontekst w ramach zestawu powiązanych witryn” to kontekst, np. iframe, którego witryna z wstawioną treścią i witryna najwyższego poziomu znajdują się w tym samym zestawie powiązanych witryn).

Sprawdzanie i proszenie o dostęp do pamięci masowej

Aby sprawdzić, czy mają obecnie dostęp do pamięci, umieszczone witryny mogą użyć metody Document.hasStorageAccess().

Metoda zwraca obietnicę, która zwraca wartość logiczną wskazującą, czy dokument ma już dostęp do swoich plików cookie. Obietnica zwraca też wartość true, jeśli element iframe ma ten sam element docelowy co element najwyższego poziomu.

Aby poprosić o dostęp do plików cookie w kontekście wielu witryn, umieszczone strony mogą używać Document.requestStorageAccess()(rSA).

Interfejs API requestStorageAccess() należy wywoływać z poziomu elementu iframe. Element iframe musi zostać właśnie wywołany przez użytkownika (gestyk, który jest wymagany przez wszystkie przeglądarki), ale w przypadku Chrome dodatkowo musi się zdarzyć, aby w jakimś momencie w ciągu ostatnich 30 dni użytkownik odwiedził witrynę, do której należy ten element iframe, i wchodził z nią w interakcję – jako dokument najwyższego poziomu, a nie w ramach elementu iframe.

requestStorageAccess() zwraca obietnicę, która jest spełniona, jeśli dostęp do pamięci został przyznany. Obietnica jest odrzucana z wspomnianym powodem, jeśli dostęp został odrzucony z jakiegokolwiek powodu.

requestStorageAccessFor w Chrome

Browser Support

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

Source

Interfejs Storage Access API umożliwia tylko witrynom z umieszczonymi treściami prosić o dostęp do pamięci masowej z elementów <iframe>, które zostały wywołane przez użytkownika.

Powoduje to trudności w wdrażaniu interfejsu Storage Access API w przypadku witryn najwyższego poziomu, które używają obrazów w wielu witrynach lub tagów skryptu wymagających plików cookie.

Aby rozwiązać ten problem, w Chrome udostępniono sposób umożliwiający witrynom najwyższego poziomu żądanie dostępu do pamięci w imieniu określonych źródeł za pomocą Document.requestStorageAccessFor() (rSAFor).

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

Interfejs API requestStorageAccessFor() powinien być wywoływany przez dokument najwyższego poziomu. Dokument musi też zostać właśnie wyświetlony użytkownikowi. Jednak w odróżnieniu od requestStorageAccess() Chrome nie sprawdza interakcji w dokumentach najwyższego poziomu z ostatnich 30 dni, ponieważ użytkownik jest już na stronie.

Sprawdzanie uprawnień dostępu do pamięci

Dostęp do niektórych funkcji przeglądarki, takich jak kamera czy geolokalizacja, zależy od uprawnień przyznanych przez użytkownika. Interfejs Permissions API umożliwia sprawdzenie stanu uprawnień dostępu do interfejsu API – czy zostały one przyznane, odrzucone czy wymagają interakcji użytkownika, np. kliknięcia promptu lub interakcji ze stroną.

Zapytanie o stan uprawnień możesz wysłać za pomocą funkcji navigator.permissions.query().

Aby sprawdzić uprawnienia dostępu do miejsca na dane w bieżącym kontekście, musisz przekazać w ciągu 'storage-access':

navigator.permissions.query({name: 'storage-access'})

Aby sprawdzić uprawnienia dostępu do miejsca na dane dla określonego źródła, musisz przekazać w ciągu 'top-level-storage-access':

navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'})

Aby chronić integralność zaszyfrowanego źródła, sprawdzane są tylko uprawnienia przyznane przez dokument najwyższego poziomu za pomocą elementu document.requestStorageAccessFor.

W zależności od tego, czy uprawnienie może zostać przyznane automatycznie, czy wymaga działania użytkownika, zwróci wartość prompt lub granted.

Model na ramkę

Przyznawanie uprawnień rSA odbywa się na podstawie ramki. Uprawnienia rSA i rSAFor są traktowane jako osobne uprawnienia.

Każda nowa ramka musi osobno poprosić o dostęp do pamięci masowej, a dostęp zostanie automatycznie przyznany. Tylko pierwsze żądanie wymaga działania użytkownika. Kolejne żądania inicjowane przez iframe, takie jak nawigacja czy zasoby podrzędne, nie muszą czekać na działanie użytkownika, ponieważ zostanie ono przyznane na potrzeby sesji przeglądania przez pierwsze żądanie.

Odświeżanie, ponowne wczytywanie lub ponowne tworzenie iframe wymaga ponownego wysłania prośby o dostęp.

Pliki cookie muszą zawierać atrybuty SameSite=NoneSecure, ponieważ rSA udostępnia dostęp tylko do plików cookie, które są już oznaczone do użycia w kontekście wielu witryn.

Pliki cookie z atrybutem SameSite=Lax, SameSite=Strict lub bez atrybutu SameSite są przeznaczone tylko do użytku własnego i nigdy nie będą udostępniane w kontekście wielu stron niezależnie od ustawienia rSA.

Bezpieczeństwo

W przypadku rSAFor żądania dotyczące podzasobów wymagają nagłówków współdzielenia zasobów pomiędzy serwerami z różnych domen (CORS) lub atrybutu crossorigin w zasobach, co zapewnia wyraźną zgodę.

Przykłady implementacji

Prośba o dostęp do pamięci z poziomu osadzonego międzyźródłowego elementu iframe

Schemat przedstawiający osadzoną witrynę na stronie najwyższego poziomu
Używanie requestStorageAccess() w umieszczonym filmie w innej witrynie

Sprawdzanie, czy masz dostęp do pamięci

Aby sprawdzić, czy masz już dostęp do pamięci masowej, użyj document.hasStorageAccess().

Jeśli obietnica zwróci wartość true, możesz uzyskać dostęp do pamięci w kontekście międzywitrynowym. Jeśli zwróci wartość fałsz, musisz poprosić o dostęp do pamięci.

document.hasStorageAccess().then((hasAccess) => {
    if (hasAccess) {
      // You can access storage in this context
    } else {
      // You have to request storage access
    }
});

Poproś o dostęp do pamięci

Jeśli musisz poprosić o dostęp do pamięci, najpierw sprawdź uprawnienia dostępu do pamięci navigator.permissions.query({name: 'storage-access'}), aby dowiedzieć się, czy wymagają one działania użytkownika czy mogą być przyznane automatycznie.

Jeśli uprawnienie to granted, możesz wywołać document.requestStorageAccess(), co powinno się udać bez interakcji użytkownika.

Jeśli stan uprawnień to prompt, musisz zainicjować wywołanie document.requestStorageAccess() po wykonaniu przez użytkownika odpowiedniego gestu, np. kliknięciu przycisku.

Przykład:

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
      }
    );
  }
}

Kolejne żądania z ramki, nawigacji lub podzasobów będą automatycznie mieć uprawnienia do dostępu do plików cookie w różnych witrynach. hasStorageAccess() zwraca wartość true, a pliki cookie z innych witryn z tego samego zestawu powiązanych witryn będą wysyłane w ramach tych żądań bez dodatkowych wywołań JavaScript.

Witryny najwyższego poziomu żądające dostępu do plików cookie w imieniu witryn w różnych domenach

Diagram pokazujący użycie funkcji requestStorageAccessFor() w witrynie najwyższego poziomu, a nie w ramach elementu osadzonego
Używanie requestStorageAccessFor() w witrynie najwyższego poziomu dla innego źródła

Strony najwyższego poziomu mogą używać zasady requestStorageAccessFor(), aby żądać dostępu do miejsca na dane w imieniu określonych źródeł.

hasStorageAccess() sprawdza tylko, czy wywołująca go witryna ma dostęp do pamięci. Dzięki temu witryna najwyższego poziomu może sprawdzić uprawnienia dla innego źródła.

Aby sprawdzić, czy użytkownik otrzyma prośbę o dostęp lub czy dostęp do pamięci został już przyznany określonemu źródłu, wywołaj funkcję navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'}).

Jeśli uprawnienia to granted, możesz wywołać funkcję document.requestStorageAccessFor('https://target.site'). Powinien on się powieść bez interakcji użytkownika.

Jeśli uprawnienia to prompt, musisz wywołać funkcję document.requestStorageAccessFor('https://target.site') po wykonaniu przez użytkownika odpowiedniego gestu, np. kliknięcia przycisku.

Przykład:

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
      }
    );
  }
}

Po wywołaniu funkcji requestStorageAccessFor() żądania między witrynami będą zawierać pliki cookie, jeśli zawierają CORS lub atrybut crossorigin, więc witryny mogą chcieć poczekać, zanim wyślą żądanie.

Żądania muszą używać opcji credentials: 'include', a zasoby muszą zawierać atrybut 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
      });
  }

Jak przetestować lokalnie

Wymagania wstępne

Aby przetestować zestawy powiązanych stron lokalnie, uruchom Chrome 119 lub nowszą wersję z wiersza poleceń i włącz test-third-party-cookie-phaseout flagę Chrome.

Włącz flagę w Chrome

Aby włączyć flagę Chrome, na pasku adresu otwórz chrome://flags#test-third-party-cookie-phaseout i zmień flagę na Enabled. Po zmianie flag uruchom ponownie przeglądarkę.

Uruchom Chrome z lokalnym zestawem powiązanych witryn

Aby uruchomić Chrome z lokalnie zadeklarowanym zestawem powiązanych witryn, utwórz obiekt JSON zawierający adresy URL, które są elementami zestawu, i przekaż go do --use-related-website-set.

Dowiedz się więcej o uruchamianiu Chromium z flagami.

--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/

Przykład

Aby włączyć zestawy powiązanych witryn lokalnie, musisz włączyć opcję test-third-party-cookie-phaseout w pliku chrome://flags i uruchomić Chrome z linii poleceń z flagą --use-related-website-set zawierającą obiekt JSON z adresami URL, które są elementami zestawu.

--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/

Sprawdź, czy masz dostęp do plików cookie w wielu witrynach

Wywołuj interfejsy API (rSA lub rSAFor) z witryn, które są testowane, i sprawdź dostęp do plików cookie między witrynami.

Proces przesyłania zestawów powiązanych witryn

Aby zadeklarować relację między domenami i określić, do której podgrupy należą, wykonaj te czynności.

1. Identyfikowanie RWS

Określ odpowiednie domeny, w tym witrynę główną zestawuwitryny członkowskie, które będą częścią zestawu powiązanych witryn. Określ też, do jakiego typu podzbioru należy każdy element zbioru.

2. Tworzenie zgłoszenia RWS

Utwórz lokalną kopię (klon lub rozwidlenie) repozytorium GitHub. W nowej gałęzi wprowadź zmiany w pliku related_website_sets.JSON, aby odzwierciedlały Twój zestaw. Aby mieć pewność, że zestaw ma prawidłowe formatowanie i strukturę JSON, możesz użyć narzędzia Generatora JSON.

3. Sprawdź, czy usługa RWS spełnia wymagania techniczne

Upewnij się, że są spełnione wymagania dotyczące tworzenia zestawów i sprawdzanie zestawów.

4. Testowanie usługi RWS lokalnie

Zanim utworzysz pull request (PR), aby przesłać zestaw, przetestuj przesyłane dane lokalnie, aby upewnić się, że spełniają wszystkie wymagania.

5. Przesyłanie zestawu powiązanych witryn

Prześlij zestaw powiązanych witryn, tworząc PR do pliku related_website_sets.JSON, w którym Chrome hostuje kanoniczną listę zestawów powiązanych witryn. (aby tworzyć PR-y, musisz mieć konto GitHub i podpisać Umowę licencyjną dla współtwórców (CLA), aby mógł tworzyć listy).

Po utworzeniu wersji roboczej przeprowadzana jest seria kontroli, aby upewnić się, że są spełnione wymagania z kroku 3. Sprawdzamy na przykład, czy plik .well-known jest prawidłowy i czy została podpisana umowa o nierozpowszechnianiu informacji.

Jeśli proces się powiedzie, w zgłoszeniu pojawi się informacja, że wszystkie testy zostały zaliczone. Zatwierdzone zmiany zostaną ręcznie scalone w partiach z kanoniczną listą zestawów powiązanych witryn raz w tygodniu (we wtorki o 12:00 czasu wschodniego). Jeśli któryś z testów wykryje błędy, osoba przesyłająca zostanie powiadomiona o nieudanym procesie PR w GitHubu. Osoba przesyłająca może poprawić błędy i zaktualizować PR. Pamiętaj, że:

  • Jeśli proces przesyłania danych do Google kończy się niepowodzeniem, w komunikacie o błędzie znajdziesz dodatkowe informacje o przyczynie niepowodzenia. (na przykład).
  • Wszystkie kontrole techniczne dotyczące przesyłania zestawów są przeprowadzane w GitHubie, dlatego wszystkie błędy przesyłania wynikające z kontroli technicznych będą widoczne w GitHubie.

Zasady dotyczące firm

Chrome ma 2 zasady, które spełniają potrzeby użytkowników korporacyjnych:

  • Systemy, które mogą nie być w stanie zintegrować się z zestawami powiązanych witryn, mogą wyłączyć tę funkcję we wszystkich instancjach Chrome Enterprise za pomocą zasady RelatedWebsiteSetsEnabled.
    • Niektóre systemy korporacyjne mają witryny tylko dla użytkowników wewnętrznych (np. intranet) z możliwością rejestracji domen, które różnią się od domen w zestawie powiązanych witryn. Jeśli użytkownik musi traktować te witryny jako część zestawu powiązanych witryn, ale nie chce ich ujawniać publicznie (ponieważ domeny mogą być poufne), może uzupełnić lub zastąpić publiczną listę zestawów powiązanych witryn za pomocą zasady RelatedWebsiteSetsOverrides.

Chrome rozwiązuje dowolne przecięcie zbiorów publicznych i firmowych na jeden z 2 sposobów, w zależności od tego, czy podano wartość replacements czy additions.

Na przykład w przypadku publicznego zbioru {primary: A, associated: [B, C]}:

replacements seta: {primary: C, associated: [D, E]}
Zestaw firmowy pochłania wspólną witrynę, tworząc nowy zestaw.
Wyniki: {primary: A, associated: [B]}
{primary: C, associated: [D, E]}
additions seta: {primary: C, associated: [D, E]}
Zestawy publiczne i Enterprise są łączone.
Utworzony zestaw: {primary: C, associated: [A, B, D, E]}

Rozwiązywanie problemów z zestawami powiązanych witryn

„Wezwanie użytkownika” i „Ruch użytkownika”

„Prośba do użytkownika” i „gestyk użytkownika” to różne rzeczy. Chrome nie wyświetla prośby o uprawnienia w przypadku witryn należących do tego samego zestawu powiązanych witryn, ale Chrome nadal wymaga, aby użytkownik nawiązał interakcję ze stroną. Przed przyznaniem uprawnienia Chrome wymaga gestu użytkownika, zwanego też „interakcją użytkownika” lub „aktywacją użytkownika”. Wynika to z tego, że korzystanie z interfejsu Storage Access API poza kontekstem zestawu powiązanych witryn (czyli requestStorageAccess()) wymaga również działania użytkownika ze względu na zasady projektowania platformy internetowej.

Dostęp do plików cookie lub pamięci innych witryn

Zestawy powiązanych witryn nie scalają pamięci różnych witryn: umożliwiają tylko łatwiejsze (bez promptów) wywołania requestStorageAccess(). Zestawy powiązanych witryn tylko zmniejszają trudności związane z korzystaniem z interfejsu Storage Access API, ale nie określają, co należy zrobić po przywróceniu dostępu. Jeśli A i B to różne witryny należące do tego samego zestawu powiązanych witryn, a A zawiera B, witryna B może wywołać interfejs requestStorageAccess() i uzyskać dostęp do pamięci własnej bez wyświetlania prośby użytkownikowi. Powiązane zestawy witryn nie wykonują żadnej komunikacji między witrynami. Na przykład skonfigurowanie zestawu powiązanych witryn nie spowoduje, że pliki cookie należące do witryny B zaczną być wysyłane do witryny A. Jeśli chcesz udostępnić te dane, musisz zrobić to samodzielnie, na przykład wysyłając window.postMessage z ramki IFrame w B do ramki A.

Zestawy powiązanych witryn nie zezwalają na domyślny dostęp do plików cookie bez wywoływania interfejsu API. Pliki cookie między witrynami nie są udostępniane domyślnie w ramach zestawu. Zestawy powiązanych witryn umożliwiają tylko witrynom w zestawie pominięcie prośby o przyznanie uprawnień interfejsu Storage Access API. Element iframe musi wywołać funkcję document.requestStorageAccess(), jeśli chce uzyskać dostęp do plików cookie. Strona najwyższego poziomu może też wywołać funkcję document.requestStorageAccessFor().

Podziel się opinią

Przesyłanie zestawu na GitHubie oraz korzystanie z interfejsów Storage Access API i requestStorageAccessFor API to okazja do podzielenia się swoimi doświadczeniami związanymi z tym procesem i wszelkimi problemami, na które natkniesz się w trakcie jego realizacji.

Aby dołączyć do dyskusji na temat zestawów powiązanych witryn: