Interfejs Storage Access API

Blokowanie plików cookie innych firm przez przeglądarki, ustawienia użytkownika i partycjonowanie pamięci stanowią wyzwanie dla witryn i usług, które polegają na plikach cookie i innych magazynach w ramach wbudowanych kontekstów, np. w przypadku uwierzytelniania. Dzięki interfejsowi Storage Access API (SAA) te przypadki użycia mogą działać bez zakłóceń, jednocześnie ograniczając śledzenie w witrynach.

Stan wdrożenia

Obsługa przeglądarek

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

Źródło

Interfejs Storage Access API jest dostępny we wszystkich najpopularniejszych przeglądarkach, ale występują niewielkie różnice we wdrożeniu w poszczególnych przeglądarkach. Różnice te zostały wyróżnione w odpowiednich sekcjach tego posta.

Nadal pracujemy nad rozwiązaniem wszystkich pozostałych problemów z blokowaniem, zanim standaryzujemy interfejs API.

Czym jest interfejs Storage Access API?

Storage Access API to interfejs JavaScript API, który umożliwia elementom iframe żądanie uprawnień dostępu do pamięci masowej, gdy dostęp jest odmawiany przez ustawienia przeglądarki. Elementy umieszczone z przypadkami użycia, które zależą od wczytywania zasobów z innej witryny, w razie potrzeby mogą używać interfejsu API, aby w razie potrzeby poprosić użytkownika o przyznanie uprawnień dostępu.

Jeśli prośba o miejsce na dane zostanie udzielona, element iframe będzie miał dostęp do niepartycjonowanych plików cookie i pamięci, które są też dostępne dla użytkowników odwiedzających go jako witrynę najwyższego poziomu.

Interfejs Storage Access API umożliwia udostępnianie dostępu do niepartycjonowanych plików cookie i niepartycjonowanej pamięci z minimalnym obciążeniem dla użytkownika, a jednocześnie zapobiega ogólnemu dostępowi do niepartycjonowanych plików cookie i niepartycjonowanej pamięci, który jest często wykorzystywany do śledzenia użytkowników.

Przypadki użycia

Niektóre elementy osadzenia innych firm wymagają dostępu do niepartycjonowanych plików cookie lub pamięci, aby zapewnić użytkownikom lepsze wrażenia. Nie będzie to możliwe, gdy pliki cookie innych firm są ograniczone, a partycjonowanie pamięci jest włączone.

Zastosowania:

  • Umieszczone widżety komentarzy, które wymagają szczegółów sesji logowania.
  • przyciski „Lubię to” w mediach społecznościowych, które wymagają podania danych logowania;
  • osadzone dokumenty, które wymagają danych sesji logowania;
  • Zaawansowane funkcje dostępne w ramach wbudowanego filmu (np. brak wyświetlania reklam użytkownikom, którzy się zalogowali, czy poznawanie preferencji użytkownika dotyczących napisów lub ograniczanie niektórych typów filmów).
  • Wbudowane systemy płatności.

Wiele z tych przypadków użycia obejmuje trwały dostęp do logowania w osadzonych elementach iframe.

Kiedy warto używać interfejsu Storage Access API zamiast innych interfejsów API

Interfejs Storage Access API jest jedną z alternatyw dla niepartycjonowanych plików cookie i przechowywania, dlatego warto wiedzieć, kiedy używać tego interfejsu API w porównaniu z innymi. Jest przeznaczony do zastosowań, w których spełnione są oba te warunki:

  • Użytkownik będzie wchodzić w interakcję z zawartością, która jest umieszczona w ramce, czyli nie jest to pasywna ani ukryta rama iframe.
  • Użytkownik skorzystał z umieszczonego źródła w kontekście najwyższego poziomu, czyli gdy nie jest ono umieszczone w innej witrynie.

Do różnych zastosowań dostępne są alternatywne interfejsy API:

  • Pliki cookie mające stan niezależnej partycji (CHIPS) pozwalają programistom włączyć pliki cookie „dzielone na partycje” z osobnym plikiem cookie dla każdej witryny najwyższego poziomu. Na przykład widget czatu internetowego innej firmy może używać pliku cookie do zapisywania informacji o sesji. Informacje o sesji są zapisywane dla poszczególnych witryn, więc plik cookie ustawiany przez widżet nie musi być używany w innych witrynach, w których także jest umieszczony. Interfejs Storage Access API jest przydatny, gdy wbudowany widżet zewnętrzny zależy od udostępniania tych samych informacji z różnych źródeł (np. szczegółów sesji lub preferencji).
  • Partycjonowanie pamięci to sposób, dzięki któremu tagi iframe na wielu stronach mogą korzystać z dotychczasowych mechanizmów pamięci JavaScript, dzieląc pamięć na poszczególne strony. Dzięki temu nie można uzyskać dostępu do zasobów pamięci w ramach wbudowanego elementu w innych witrynach.
  • Zestawy powiązanych witryn (RWS) to sposób na deklarowanie przez organizację relacji między witrynami, dzięki którym przeglądarki zezwalają na ograniczony, niepartycjonowany dostęp do plików cookie i do pamięci na potrzeby określonych celów. Witryny nadal muszą prosić o dostęp za pomocą interfejsu Storage Access API, ale w przypadku witryn z danego zbioru dostęp może być przyznawany bez wyświetlania użytkownikowi odpowiednich komunikatów.
  • Federated Credential Management (FedCM) to chroniące prywatność podejście do usług tożsamości sfederowanej. Interfejs Storage Access API umożliwia dostęp do niezapartionowanych plików cookie i przechowywania po zalogowaniu się. W niektórych przypadkach FedCM może być preferowanym rozwiązaniem w związku z interfejsem Storage Access API, ponieważ zawiera ono prompt przeglądarki bardziej zorientowany na logowanie. Jednak wdrożenie FedCM zwykle wymaga wprowadzenia dodatkowych zmian w kodzie, np. w celu obsługi punktów końcowych HTTP.
  • Istnieją również interfejsy API do zapobiegania oszustwom, związanych z reklamami i pomiarów, a interfejs Storage Access API nie służy do rozwiązywania tych wątpliwości.

Korzystanie z interfejsu Storage Access API

Interfejs Storage Access API udostępnia 2 metody oparte na obietnicy:

Integruje się też z interfejsem Permissions API. Umożliwia to sprawdzenie w kontekście innej firmy stanu uprawnień dostępu do pamięci masowej, który wskazuje, czy wywołanie funkcji document.requestStorageAccess() zostanie przyznane automatycznie:

Użyj metody hasStorageAccess()

Po pierwszym wczytaniu strona może użyć metody hasStorageAccess(), aby sprawdzić, czy dostęp do plików cookie innych firm został już przyznany.

// 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();

Dostęp do pamięci masowej jest przyznawany dokumentowi iframe po wywołaniu funkcji requestStorageAccess(),, więc hasStorageAccess() zawsze zwraca wartość „false” na początku. Wyjątkiem jest sytuacja, gdy inny dokument tej samej domeny w tym samym elemencie iframe ma już przyznany dostęp. Uprawnienia są zachowywane w ramach nawigacji w tym samym źródle w elemecie iframe, aby umożliwić ponowne wczytywanie po przyznaniu dostępu na stronach, które wymagają obecności plików cookie w pierwotnym żądaniu dokumentu HTML.

Użyj konta requestStorageAccess()

Jeśli element iframe nie ma dostępu, może poprosić o dostęp za pomocą metody requestStorageAccess():

if (!hasAccess) {
  try {
    await document.requestStorageAccess();
  } catch (err) {
    // Access was not granted and it may be gated behind an interaction
    return;
  }
}

Przy pierwszym żądaniu użytkownik może być zobowiązany do zatwierdzenia dostępu za pomocą komunikatu w przeglądarce. Po tym czasie obietnica zostanie zrealizowana lub odrzuci prośbę, jeśli użyjesz await.

Aby zapobiec nadużyciom, ta prośba w przeglądarce będzie wyświetlana dopiero po interakcji użytkownika. Dlatego funkcja requestStorageAccess() musi być wywoływana z obsługi zdarzeń aktywowanych przez użytkownika, a nie natychmiast po załadowaniu ramki 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);

Jeśli chcesz używać lokalnego magazynu zamiast plików cookie, możesz:

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

Prośby o przyznanie uprawnień

Gdy użytkownik kliknie przycisk po raz pierwszy, w przeglądarce automatycznie pojawi się odpowiedni komunikat, zwykle na pasku adresu. Na poniższym zrzucie ekranu widać prośbę w Chrome, ale inne przeglądarki mają podobny interfejs:

Prośba o przyznanie uprawnień do interfejsu Storage Access API w Chrome
Prośba o przyznanie uprawnień do interfejsu Storage Access API w Chrome

Przeglądarka może pominąć ten prompt, a uprawnienia przyznawane automatycznie w określonych okolicznościach:

  • Jeśli strona i ramka iframe były używane w ciągu ostatnich 30 dni od zaakceptowania prośby.
  • Jeśli umieszczony element iframe jest częścią zestawu powiązanych witryn.
  • W Firefoksie ten komunikat jest również pomijany w przypadku znanych witryn (z którymi użytkownik wejdzie w interakcję na najwyższym poziomie) przez pierwsze 5 prób.

W pewnych okolicznościach metoda może też zostać automatycznie odrzucona bez wyświetlania prośby:

  • Jeśli użytkownik wcześniej nie wchodził w interakcję z witryną, w której znajduje się element iframe, jako dokument najwyższego poziomu, a nie w elemencie iframe. Oznacza to, że interfejs Storage Access API jest przydatny tylko w przypadku osadzionych witryn, które użytkownicy odwiedzili wcześniej w kontekście własnych aplikacji.
  • Jeśli metoda requestStorageAccess() zostanie wywołana poza zdarzeniem interakcji z użytkownikiem bez wcześniejszego zatwierdzenia promptu po interakcji.

Użytkownik zostanie poproszony przy pierwszym użyciu, ale po kolejnych wizytach może rozwiązać requestStorageAccess() bez pytania i bez konieczności interakcji ze strony użytkownika w Chrome i Firefoksie. Pamiętaj, że Safari zawsze wymaga interakcji ze strony użytkownika.

Ponieważ dostęp do plików cookie i miejsca do przechowywania może być przyznany bez wyświetlania promptu lub interakcji z użytkownikiem, w przeglądarkach, które obsługują tę funkcję (Chrome i Firefox), często można uzyskać dostęp do niepartycjonowanych plików cookie lub miejsca do przechowywania przed interakcją z użytkownikiem, wywołując requestStorageAccess() podczas wczytywania strony. Dzięki temu możesz natychmiast uzyskać dostęp do plików cookie i pamięci bez partycji oraz zapewnić więcej możliwości, jeszcze zanim użytkownik wejdzie w interakcję z elementem iframe. W niektórych sytuacjach może to być wygodniejsze dla użytkownika niż czekanie na interakcję.

Używanie zapytania o uprawnienia storage-access

Aby sprawdzić, czy dostęp można przyznać bez interakcji użytkownika, możesz sprawdzić stan uprawnienia storage-access i wywołać requestStoreAccess() z wyprzedzeniem tylko wtedy, gdy nie jest wymagane żadne działanie użytkownika, zamiast je wywoływać, gdy wymagana jest interakcja.

Dzięki temu możesz też szybciej zareagować na prośbę o zgodę, wyświetlając inną treść, na przykład przycisk logowania.

Poniższy kod dodaje do poprzedniego przykładu sprawdzenie uprawnień 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();

Elementy iframe w piaskownicy

Podczas korzystania z interfejsu Storage Access API w ramkach iframe w piaskownicy wymagane są te uprawnienia piaskownicy:

  • Aby zezwolić na dostęp do interfejsu Storage Access API, wymagane jest uprawnienie allow-storage-access-by-user-activation.
  • Aby umożliwić wywoływanie interfejsu API za pomocą JavaScriptu, musisz ustawić parametr allow-scripts.
  • Parametr allow-same-origin jest wymagany, aby umożliwić dostęp do plików cookie tej samej domeny i innych pamięci.

Na przykład:

<iframe sandbox="allow-storage-access-by-user-activation
                 allow-scripts
                 allow-same-origin"
        src="..."></iframe>

Aby można było uzyskać dostęp do interfejsu Storage Access API w Chrome, pliki cookie należące do różnych witryn muszą być skonfigurowane za pomocą tych 2 atrybutów:

  • SameSite=None – wymagane do oznaczenia pliku cookie jako pochodzącego z innej witryny;
  • Secure – zapewnia dostęp tylko do plików cookie ustawionych przez witryny HTTPS.

W przeglądarkach Firefox i Safari pliki cookie mają domyślnie wartość SameSite=None. Nie ograniczają one SAA do plików cookie Secure, więc te atrybuty nie są wymagane. Zalecamy wyraźne określenie atrybutu SameSite i zawsze używanie plików cookie Secure.

Dostęp do strony najwyższego poziomu

Interfejs Storage Access API służy do włączania dostępu do plików cookie innych firm w ramach wbudowanych elementów iframe.

Istnieją też inne przypadki użycia, gdy strona najwyższego poziomu wymaga dostępu do plików cookie innych firm. Na przykład obrazy lub skrypty ograniczone przez pliki cookie, które właściciele witryn mogą chcieć umieścić bezpośrednio w dokumentach najwyższego poziomu, a nie w ramkach iframe. Aby rozwiązać ten problem, Chrome zaproponował rozszerzenie interfejsu Storage Access API, które dodaje metodę requestStorageAccessFor().

Metoda requestStorageAccessFor()

Obsługa przeglądarek

  • Chrome: 119.
  • Edge: 119.
  • Firefox: nieobsługiwane.
  • Safari: nieobsługiwane.

Źródło

Metoda requestStorageAccessFor() działa podobnie jak metoda requestStorageAccess(), ale dotyczy zasobów najwyższego poziomu. Można go używać tylko w przypadku witryn z zestawu powiązanych witryn, aby uniemożliwiać przyznawanie ogólnego dostępu do plików cookie innych firm.

Więcej informacji o korzystaniu z usługi requestStorageAccessFor() znajdziesz w przewodniku dla programistów dotyczącym zestawów powiązanych witryn (w języku angielskim).

Zapytanie o uprawnienia top-level-storage-access

Obsługa przeglądarek

  • Chrome: funkcja nieobsługiwana.
  • Edge: nieobsługiwane.
  • Firefox: nieobsługiwane.
  • Safari: nieobsługiwane.

Podobnie jak w przypadku uprawnienia storage-access, istnieje uprawnienie top-level-storage-access, które pozwala sprawdzić, czy można przyznać uprawnienia requestStorageAccessFor().

Czym różni się interfejs Storage Access API w przypadku interfejsu RWS?

Gdy z interfejsem Storage Access API są używane zestawy powiązanych witryn, dostępne są pewne dodatkowe możliwości, jak opisano w tej tabeli:

Bez RWS Z RWS
Wymaga gestu użytkownika do zainicjowania prośby o dostęp do pamięci masowej
Wymaga, aby użytkownik odwiedził żądane źródło danych w kontekście najwyższego poziomu, zanim przyzna dostęp.
Prośba o zaakceptowanie warunków przez nowego użytkownika może zostać pominięta
Funkcja requestStorageAccess nie musi być wywoływana, jeśli dostęp został wcześniej przyznany
automatycznie przyznaje dostęp do innych domen w witrynie powiązanej.
Obsługuje requestStorageAccessFor na poziomie strony najwyższego poziomu
Różnice między używaniem interfejsu Storage Access API bez zestawów powiązanych witryn i bez nich

Prezentacja: ustawianie i dostęp do plików cookie

Poniższa demonstracja pokazuje, jak można uzyskać dostęp do pliku cookie ustawionego przez Ciebie na pierwszym ekranie prezentacji w ramce umieszczonej w drugiej witrynie:

storage-access-api-demo.glitch.me

Wersja demonstracyjna wymaga przeglądarki z wyłączonymi plikami cookie innych firm:

  • Chrome w wersji 118 lub nowszej z ustawioną flagą chrome://flags/#test-third-party-cookie-phaseout i ponownie uruchomioną przeglądarką.
  • Firefox
  • Safari

Demonstracja: konfigurowanie pamięci lokalnej

Ten pokaz demonstruje, jak uzyskać dostęp do niepartycjonowanych kanałów transmisji za pomocą interfejsu Storage Access API:

https://saa-beyond-cookies.glitch.me/

Demonstracja wymaga wersji Chrome 125 lub nowszej z włączoną flagą test-third-party-cookie-phaseout.

Zasoby