Interfejs Storage Access API

Chrome wycofuje obsługę plików cookie innych firm i pamięć partycjonującą, aby ograniczyć śledzenie w witrynach. Stanowi to wyzwanie dla witryn i usług, które bazują na plikach cookie i innych rodzajach pamięci w umieszczonych kontekstach, na przykład podczas 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 implementacji

Obsługa przeglądarek

  • 119
  • 85
  • 65
  • 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.

Pracujemy nad rozwiązaniem wszystkich pozostałych problemów blokujących przed standaryzacją interfejsu API.

Czym jest interfejs Storage Access API?

Storage Access API to interfejs API JavaScript, który umożliwia elementom iframe wysyłanie próśb o przyznanie uprawnień dostępu do pamięci, jeśli dostęp zostałby zablokowany 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 zapewnienie dostępu do określonych plików cookie i pamięci bez partycji przy minimalnym nakładzie pracy użytkownika, a jednocześnie pozwala zapobiec ogólnikowemu dostępowi do plików cookie i pamięci, które są często wykorzystywane do śledzenia użytkowników.

Przykłady zastosowań

Niektóre elementy osadzone innych firm wymagają dostępu do niepartycjonowanych plików cookie lub pamięci, aby zapewnić większy komfort użytkownikom. Ta funkcja nie będzie dostępna po wycofaniu plików cookie innych firm i włączeniu partycjonowania pamięci.

Zastosowania:

  • Umieszczone widżety komentarzy, które wymagają szczegółów sesji logowania.
  • przyciski „Podoba mi się” w mediach społecznościowych, które wymagają danych sesji logowania;
  • Umieszczone dokumenty, które wymagają szczegółów sesji logowania.
  • Płatne funkcje, które są dostępne w przypadku osadzonych filmów (np. w celu uniemożliwienia wyświetlania reklam zalogowanym użytkownikom, poznania preferencji użytkownika dotyczących napisów lub ograniczenia określonych typów filmów).
  • Wbudowane systemy płatności.

Wiele z tych przypadków użycia wiąże się z utrzymaniem dostępu do logowania w umieszczonych elementach iframe.

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

Interfejs Storage Access API to jedna z alternatyw dla niepartycjonowanych plików cookie i pamięci masowej, dlatego ważne jest, aby wiedzieć, kiedy używać tego interfejsu API w porównaniu z innymi. Mają zastosowanie w przypadkach, w których są spełnione oba te warunki:

  • Użytkownik wchodzi w interakcję z umieszczoną treścią – nie jest to pasywny element iframe ani ukryty element iframe.
  • Użytkownik skorzystał z umieszczonego źródła w kontekście najwyższego poziomu, czyli gdy nie jest ono umieszczone w innej witrynie.

Istnieją alternatywne interfejsy API do różnych zastosowań:

  • Pliki cookie o niezależnym stanie partycjonowania (ang. Independent Partyitioned State) (CHIPS) umożliwiają deweloperom umieszczenie pliku cookie w „partycjonowanej” pamięci z osobnym kontenerem na pliki cookie dla każdej witryny najwyższego poziomu. Na przykład widżet czatu internetowego innej firmy może polegać na ustawieniu 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 umieszczony widżet innej firmy wymaga udostępniania tych samych informacji między różnymi źródłami (na przykład szczegółów lub ustawień zalogowanej sesji).
  • partycjonowanie miejsca na dane to sposób, w jaki elementy iframe z innych witryn mogą korzystać z istniejących mechanizmów przechowywania danych w języku JavaScript, a przy tym dzielić bazową ilość miejsca na dane dla poszczególnych witryn. Zapobiega to uzyskiwaniu dostępu do pamięci umieszczonej w jednej witrynie przez ten sam element umieszczony na innych stronach.
  • Zestawy powiązanych witryn (RWS) to sposób na deklarowanie przez organizację relacji między witrynami. Dzięki temu przeglądarki umożliwiają przeglądarkom ograniczony dostęp do plików cookie i ich przechowywania w określonych celach. Witryny nadal muszą prosić o dostęp za pomocą interfejsu Storage Access API, ale w przypadku witryn w zestawie można przyznać dostęp bez pytania użytkownika.
  • 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 niepartycjonowanych plików cookie i miejsca na dane po zalogowaniu. W niektórych przypadkach FedCM stanowi alternatywne rozwiązanie w stosunku do interfejsu Storage Access API. Może ono być lepsze, ponieważ wyświetla komunikat bardziej zorientowany na logowanie się w przeglądarce. Wdrożenie FedCM zwykle jednak wymaga jednak dodatkowych zmian w kodzie, na przykład 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 ma 2 obiecane metody:

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:

Korzystanie z 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 via 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. Uwierzytelnienie jest zachowywane w obrębie elementów nawigacyjnych tej samej domeny w elemencie iframe, aby umożliwić ponowne załadowanie po przyznaniu dostępu stronom, które wymagają, aby w początkowym żądaniu dokumentu HTML znajdowały się pliki cookie.

Korzystanie z metody requestStorageAccess()

Jeśli element iframe nie ma dostępu, być może trzeba 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;
  }
}

Po pierwszym przesłaniu prośby 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 wyświetli się tylko po interakcji użytkownika. Z tego powodu funkcja requestStorageAccess() musi być najpierw wywołana z modułu obsługi zdarzeń aktywowanego przez użytkownika, a nie od razu po wczytaniu elementu 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 above did not reject.
    } catch (err) {
      // Access was not granted.
      return;
    }
  }

  if (hasAccess) {
    // Use the cookies
  }
}

document.querySelector('#my-button').addEventListener('click', doClick);

Jeśli zamiast plików cookie chcesz korzystać z pamięci lokalnej, 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, automatycznie pojawi się okno przeglądarki, zwykle na pasku adresu. Poniżej znajduje się przykład komunikatu Chrome, ale interfejs innych przeglądarek jest podobny:

Zrzut ekranu przedstawiający prośbę o przyznanie uprawnień do interfejsu Chrome Storage Access API
Prośba o przyznanie uprawnienia interfejsu Storage Access API w Chrome

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

  • Informacja, czy strona i element iframe były używane w ciągu ostatnich 30 dni od zaakceptowania promptu.
  • Jeśli umieszczony element iframe jest częścią zestawu powiązanych witryn.
  • W Firefoksie prośba jest też pomijana w przypadku znanych stron internetowych (tych, z których wchodzisz w interakcje na najwyższym poziomie) podczas pierwszych 5 prób.

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

  • Jeśli użytkownik nie wchodził wcześniej 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 umieszczonych na stronie witryn, które użytkownicy wcześniej odwiedzali samodzielnie.
  • Jeśli metoda requestStorageAccess() jest wywoływana poza zdarzeniem interakcji użytkownika bez uprzedniego 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.

Dostęp do plików cookie i pamięci można przyznać bez pytania lub bez interakcji użytkownika, dlatego często można uzyskać dostęp do pamięci lub plików cookie bez partycji przed interakcją użytkownika w przeglądarkach, które obsługują tę funkcję (Chrome i Firefox), przez wywołanie 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ę.

Korzystanie z 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.

Ten kod dodaje do wcześniejszego 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 older 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') {
            // Currently not used. See:
      // https://github.com/privacycg/storage-access/issues/149
      return false;
          }
    }

  // By default return false, though should really be caught by one of above.
  return false;
}

async function handleCookieAccessInit() {
  hasAccess = await hasCookieAccess();

  if (hasAccess) {
    // Use the cookies.
  }
}

handleCookieAccessInit();

Elementy iframe w trybie piaskownicy

Gdy używasz interfejsu Storage Access API w elementach iframe znajdujących się w piaskownicy, musisz mieć te uprawnienia piaskownicy:

  • Aby umożliwić dostęp do interfejsu Storage Access API, wymagana jest właściwość allow-storage-access-by-user-activation.
  • Parametr allow-scripts jest wymagany, aby można było używać JavaScriptu do wywoływania interfejsu API.
  • 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 utworzonych przez witryny HTTPS.

W przeglądarkach Firefox i Safari pliki cookie mają domyślną wartość SameSite=None. Nie ograniczają one SSA do plików cookie Secure, więc te atrybuty nie są wymagane. Zalecamy jednoznaczne informacje o atrybucie SameSite i używanie plików cookie Secure.

Dostęp do stron najwyższego poziomu

Interfejs Storage Access API umożliwia dostęp do plików cookie innych firm w osadzonych elementach iframe.

Występują też inne przypadki użycia, w których strona najwyższego poziomu wymaga dostępu do plików cookie innych firm. Dotyczy to na przykład obrazów lub skryptów ograniczonych przez pliki cookie, które właściciele witryn mogą chcieć umieścić bezpośrednio w dokumencie najwyższego poziomu, a nie w elemencie iframe. Aby rozwiązać ten problem, Chrome zaproponował rozszerzenie interfejsu Storage Access API, które dodaje metodę requestStorageAccessFor().

Metoda requestStorageAccessFor()

Obsługa przeglądarek

  • 119
  • 119
  • x
  • x

Źródło

Metoda requestStorageAccessFor() działa podobnie jak requestStorageAccess(), ale w przypadku 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

  • x
  • x
  • x
  • x

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

Czym różni się interfejs Storage Access API używany z 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 przed przyznaniem dostępu użytkownik odwiedził żądane źródło pamięci w kontekście najwyższego poziomu
Prośba użytkownika po raz pierwszy może zostać pominięta.
Funkcja requestStorageAccess nie musi być wywoływana, jeśli dostęp został wcześniej przyznany
Automatycznie przyznaje dostęp w innych domenach w witrynie powiązanej witryny
Obsługuje requestStorageAccessFor w przypadku dostępu do stron 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

Prezentacja: ustawianie pamięci lokalnej

Poniższy przykład pokazuje, jak uzyskać dostęp do bezpartycjonowanych kanałów transmisji z elementu iframe innej firmy przy użyciu interfejsu Storage Access API:

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

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

Zasoby