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 elementach pamięci w ramach wbudowanych kontekstów, np. w przypadku uwierzytelniania. Interfejs Storage Access API (SAA) umożliwia kontynuowanie tych zastosowań, jednocześnie w jak największym stopniu ograniczając śledzenie między witrynami.

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 głównych przeglądarkach, ale występują niewielkie różnice w implementacji między przeglądarkami. Te różnice zostały wyróżnione w odpowiednich sekcjach tego wpisu.

Nadal pracujemy nad rozwiązaniem wszystkich pozostałych problemów z blokowaniem, zanim ujednoliwimy 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. Wstawione treści, których przypadki użycia zależą od wczytywania zasobów w różnych witrynach, mogą używać interfejsu API do żądania od użytkownika pozwolenia na dostęp w razie potrzeby.

Jeśli żądanie miejsca na dane zostanie spełnione, element iframe będzie miał dostęp do niepartycjonowanych plików cookie i miejsca na dane, które są też dostępne, gdy użytkownicy odwiedzają go jako witrynę najwyższego poziomu.

Interfejs Storage Access API umożliwia udostępnianie dostępu do określonych 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.

Przykładowe zastosowania:

  • osadzone widżety dodawania komentarzy, które wymagają zalogowania się
  • 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ą, co oznacza, że nie jest to pasywny ani ukryty element iframe.
  • Użytkownik odwiedził osadzoną domenę w kontekście najwyższego poziomu, czyli gdy domena nie jest osadzona w innej witrynie.

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

  • Pliki cookie z niezależnym stanem partycji (ang. Cookies Having Independent Partitioned State, CHIPS) umożliwiają programistom dodanie pliku cookie do „partycjonowanego” miejsca na dane z osobnym zbiornikiem plików cookie dla każdej witryny najwyższego poziomu. Na przykład widget czatu internetowego innej firmy może używać plików cookie do zapisywania informacji o sesji. Informacje o sesji są zapisywane w poszczególnych witrynach, więc plik cookie ustawiony przez widżet nie musi być dostępny w innych witrynach, w których jest też 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 czemu przeglądarki zezwalają na ograniczony dostęp do plików cookie i do pamięci w ramach 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 podejście do usług tożsamości sfederowanej, które chroni prywatność. 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ą też interfejsy API do zapobiegania oszustwom, reklampomiarów, a interfejs Storage Access API nie jest przeznaczony do rozwiązywania tych problemów.

Korzystanie z interfejsu Storage Access API

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

Jest też zintegrowany z interfejsem Permissions API. Pozwala to sprawdzić stan uprawnienia dostępu do pamięci w kontekście aplikacji zewnętrznej, co wskazuje, czy wywołanie funkcji document.requestStorageAccess() zostanie automatycznie przyznane:

Użyj metody hasStorageAccess().

Podczas pierwszego wczytywania witryna 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 jest przyznawany dokumentowi w ramce tylko po wywołaniu funkcji requestStorageAccess(),, więc na początku hasStorageAccess() zawsze zwraca wartość false, z wyjątkiem przypadku, gdy inny dokument w tej samej domenie w tym samym iframe miał już przyznany dostęp. Uprawnienia są zachowywane w przypadku nawigacji w ramach tego samego pochodzenia w elementach iframe, aby umożliwić ponowne wczytywanie po przyznaniu dostępu do stron, 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;
  }
}

Gdy dostęp jest wymagany po raz pierwszy, użytkownik może musieć zatwierdzić go w wyświetlonym przez przeglądarkę promptzie. W przeciwnym razie zostanie wyświetlony wyjątek.await

Aby zapobiec nadużyciom, ta prośba w przeglądarce będzie wyświetlana tylko 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 uprawnienia

Gdy użytkownik kliknie przycisk po raz pierwszy, w większości przypadków automatycznie pojawi się prośba przeglądarki, 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ń interfejsu Storage Access API w Chrome

W pewnych okolicznościach przeglądarka może pominąć to promptowanie i automatycznie przyznać uprawnienia:

  • Jeśli strona i ramka iframe były używane w ciągu ostatnich 30 dni od zaakceptowania prośby.
  • jeśli wbudowany element iframe jest częścią zestawu powiązanych witryn.
  • Jeśli FedCM jest używany jako sygnał zaufania w przypadku dostępu do pamięci.
  • 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 zostać automatycznie odrzucona bez wyświetlania promptu:

  • Jeśli użytkownik nie odwiedził wcześniej witryny, której element iframe jest właścicielem, i nie wszedł z nią w interakcję, a element iframe znajduje się w dokumencie najwyższego poziomu, a nie w elementach 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 zobaczy prośbę o pierwsze użycie, ale w przypadku kolejnych wizyt requestStorageAccess() może się ona rozwiązać bez prośby i bez interakcji użytkownika w Chrome i Firefox. Pamiętaj, że w Safari zawsze wymagana jest interakcja użytkownika.

Ponieważ dostęp do plików cookie i przechowywania danych 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 pamięci masowej przed interakcją z użytkownikiem, wywołując requestStorageAccess() podczas wczytywania strony. Dzięki temu możesz mieć natychmiastowy dostęp do niepartycjonowanych plików cookie i przechowywania danych oraz zapewnić lepsze wrażenia, nawet zanim użytkownik wejdzie w interakcję z ramką iframe. W niektórych sytuacjach może to być wygodniejsze dla użytkownika niż oczekiwanie na jego reakcję.

FedCM jako sygnał zaufania w przypadku SAA

FedCM (Federated Credential Management) to podejście do usług tożsamości sfederowanej (takich jak „Zaloguj się za pomocą…”), które chroni prywatność i nie wymaga korzystania z plików cookie innych firm ani przekierowań nawigacyjnych.

Gdy użytkownik loguje się w systemie strony trzeciej, który zawiera treści z zewnętrznego dostawcy tożsamości (IdP) korzystającego z FedCM, te treści mogą automatycznie uzyskać dostęp do własnych plików cookie na poziomie najwyższym bez podziału na partycje. Aby włączyć automatyczny dostęp do miejsca na dane za pomocą FedCM, musisz spełnić te warunki:

  • Uwierzytelnianie w FedCM (stan logowania użytkownika) musi być aktywne.
  • RP wyraził zgodę, ustawiając uprawnienie identity-credentials-get, na przykład:
<iframe src="https://idp.example" allow="identity-credentials-get"></iframe>

Na przykład element iframe idp.example jest umieszczony w witrynie rp.example. Gdy użytkownik zaloguje się za pomocą FedCM, element iframe idp.example może poprosić o dostęp do pamięci dla własnych plików cookie najwyższego poziomu.

rp.example wysyła wywołanie do FedCM, aby zalogować użytkownika za pomocą dostawcy tożsamości idp.example:

// The user will be asked to grant FedCM permission.
const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/fedcm.json',
      clientId: '123',
    }],
  },
});

Gdy użytkownik się zaloguje, dostawca tożsamości może wywołać funkcję requestStorageAccess() z poziomu elementu iframe idp.example, o ile usługa RP wyraźnie zezwoliła na to w zasadach dotyczących uprawnień. Elementowi embed zostanie automatycznie przyznany dostęp do pamięci dla własnego najwyższego poziomu plików cookie bez aktywacji przez użytkownika lub konieczności wyświetlenia kolejnego okna z prośbą o zgodę:

// Make this call within the embedded IdP iframe:

// No user gesture is needed, and the storage access will be auto-granted.
await document.requestStorageAccess();

// This returns `true`.
const hasAccess = await document.hasStorageAccess();

Uprawnienia będą przyznawane automatycznie tylko wtedy, gdy użytkownik jest zalogowany w Federowanym systemie zarządzania kampaniami. Gdy uwierzytelnianie jest nieaktywne, standardowe wymagania SAA dotyczą przyznawania dostępu do pamięci masowej.

Używanie zapytania o uprawnienia storage-access

Aby sprawdzić, czy dostęp może być przyznany bez interakcji z użytkownikiem, możesz sprawdzić stan uprawnienia storage-access i wykonać wywołanie requestStoreAccess() w wczesniejszym etapie, jeśli nie wymaga to działania użytkownika. W przeciwnym razie wywołanie może się nie powieść.

Dzięki temu możesz też uniknąć wyświetlania prośby o pozwolenie, wyświetlając inną treść, np. 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.
  • allow-same-origin jest wymagany, aby umożliwić dostęp do plików cookie i innych danych w tej samej domenie.

Na przykład:

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

Aby można było uzyskać do nich dostęp za pomocą interfejsu Storage Access API w Chrome, pliki cookie w wielu witrynach muszą być ustawione z tymi 2 atrybutami:

  • SameSite=None – wymagane do oznaczenia pliku cookie jako pliku międzywitrynowego.
  • Secure – co zapewnia dostęp tylko do plików cookie ustawionych przez witryny HTTPS.

W Firefox i Safari domyślnie używane są pliki cookie SameSite=None i nie ograniczają one plików cookie 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 umożliwić takie działanie, Chrome proponuje 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 należących do zbioru powiązanych witryn, aby zapobiec przyznaniu ogólnego dostępu do plików cookie innych firm.

Więcej informacji o używaniu requestStorageAccessFor() znajdziesz w przewodniku dla programistów dotyczącym zestawów powiązanych witryn.

Zapytanie o uprawnienia top-level-storage-access

Obsługa przeglądarek

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

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

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

Gdy zestawy powiązanych witryn są używane z interfejsem Storage Access API, są dostępne pewne dodatkowe funkcje, jak opisano w tabeli poniżej:

Bez RWS Z RWS
Wymaga od użytkownika gestu w celu zainicjowania żądania dostępu do pamięci
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
requestStorageAccess nie wymaga wywołania, jeśli dostęp został już przyznany
automatycznie przyznaje dostęp do innych domen w witrynie powiązanej.
Obsługuje requestStorageAccessFor w przypadku dostępu do strony najwyższego poziomu
Różnice między korzystaniem z interfejsu Storage Access API bez zestawów powiązanych stron internetowych i z nimi

Demo: ustawianie plików cookie i dostęp do nich

Ten pokaz demonstruje, jak można uzyskać dostęp do pliku cookie ustawionego przez Ciebie na pierwszym ekranie w ramce umieszczonej w witrynie na drugim ekranie:

storage-access-api-demo.glitch.me

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

  • Chrome 118 lub nowszy z ustawionym flagą chrome://flags/#test-third-party-cookie-phaseout i ponownym uruchomieniem przeglądarki.
  • 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