Asynchrone toegang tot HTTP-cookies

Victor Costan

Wat is de Cookie Store-API?

De Cookie Store API stelt HTTP-cookies beschikbaar voor servicemedewerkers en biedt een asynchroon alternatief voor document.cookie . De API maakt het eenvoudiger om:

  • Vermijd rommel op de hoofdthread door asynchroon toegang te krijgen tot cookies.
  • Vermijd polling voor cookies, omdat wijzigingen in cookies kunnen worden waargenomen.
  • Toegang tot cookies van servicemedewerkers.

Lees uitleg

Huidige status

Stap Status
1. Maak een uitleg Compleet
2. Maak een eerste ontwerp van specificatie Compleet
**3. Verzamel feedback en herhaal de specificaties** **In uitvoering**
4. Oorsprongsproces Gepauzeerd
5. Lancering Niet gestart

Hoe gebruik ik de asynchrone cookie-opslag?

Schakel de origin-proefversie in

Om het lokaal uit te proberen, kan de API worden ingeschakeld op de opdrachtregel:

chrome --enable-blink-features=CookieStore

Als u deze vlag op de opdrachtregel doorgeeft, wordt de API wereldwijd in Chrome ingeschakeld voor de huidige sessie.

Als alternatief kunt u de vlag #enable-experimental-web-platform-features inschakelen in chrome://flags .

Je hebt (waarschijnlijk) geen cookies nodig

Voordat ik in de nieuwe API duik, zou ik willen zeggen dat cookies nog steeds de slechtste opslagprimitief aan de clientzijde van het webplatform zijn, en nog steeds als laatste redmiddel moeten worden gebruikt. Dit is geen toeval: cookies waren het eerste opslagmechanisme op de client, en sindsdien hebben we veel geleerd.

De belangrijkste redenen om cookies te vermijden zijn:

  • Cookies brengen uw opslagschema naar uw back-end API. Elk HTTP-verzoek bevat een momentopname van de cookie-pot. Dit maakt het voor back-end-ingenieurs gemakkelijk om afhankelijkheden van het huidige cookie-formaat te introduceren. Zodra dit gebeurt, kan uw front-end het opslagschema niet meer wijzigen zonder een passende wijziging in de back-end door te voeren.

  • Cookies hebben een complex beveiligingsmodel. Moderne webplatformfuncties volgen hetzelfde oorsprongsbeleid, wat betekent dat elke applicatie zijn eigen sandbox krijgt en volledig onafhankelijk is van andere applicaties die de gebruiker mogelijk gebruikt. Cookiescopes zorgen voor een aanzienlijk complexer beveiligingsverhaal, en alleen een poging om dat samen te vatten zou de omvang van dit artikel verdubbelen.

  • Cookies hebben hoge prestatiekosten. Browsers moeten in elk HTTP-verzoek een momentopname van uw cookies opnemen, dus elke wijziging aan cookies moet worden doorgevoerd in de opslag- en netwerkstacks. Moderne browsers hebben zeer geoptimaliseerde implementaties van cookieopslag, maar we zullen cookies nooit zo efficiënt kunnen maken als de andere opslagmechanismen, die niet met de netwerkstack hoeven te praten.

Om alle bovenstaande redenen moeten moderne webapplicaties cookies vermijden en in plaats daarvan een sessie-ID opslaan in IndexedDB , en de ID expliciet toevoegen aan de header of body van specifieke HTTP-verzoeken, via de fetch API.

Dat gezegd hebbende, lees je dit artikel nog steeds omdat je een goede reden hebt om cookies te gebruiken...

De eerbiedwaardige document.cookie API is een redelijk gegarandeerde bron van jank voor uw toepassing. Wanneer u bijvoorbeeld de document.cookie getter gebruikt, moet de browser stoppen met het uitvoeren van JavaScript totdat deze over de door u gevraagde cookie-informatie beschikt. Dit kan een processprong of schijflezen vergen, waardoor uw gebruikersinterface hapert.

Een eenvoudige oplossing voor dit probleem is het overschakelen van de document.cookie -getter naar de asynchrone Cookie Store-API.

await cookieStore.get('session_id');

// {
//   domain: "example.com",
//   expires: 1593745721000,
//   name: "session_id",
//   path: "/",
//   sameSite: "unrestricted",
//   secure: true,
//   value: "yxlgco2xtqb.ly25tv3tkb8"
// }

De document.cookie -setter kan op een vergelijkbare manier worden vervangen. Houd er rekening mee dat de wijziging alleen gegarandeerd wordt toegepast nadat de door cookieStore.set geretourneerde belofte is opgelost.

await cookieStore.set({name: 'opt_out', value: '1'});

// undefined

Observeer, peil niet

Een populaire toepassing voor toegang tot cookies uit JavaScript detecteert wanneer de gebruiker uitlogt en werkt de gebruikersinterface bij. Dit gebeurt momenteel door document.cookie te pollen, wat jank introduceert en een negatieve invloed heeft op de levensduur van de batterij.

De Cookie Store API biedt een alternatieve methode voor het observeren van cookiewijzigingen, waarvoor geen polling vereist is.

cookieStore.addEventListener('change', event => {
  for (const cookie of event.changed) {
    if (cookie.name === 'session_id') sessionCookieChanged(cookie.value);
  }
  for (const cookie of event.deleted) {
    if (cookie.name === 'session_id') sessionCookieChanged(null);
  }
});

Welkom servicemedewerkers

Vanwege synchroon ontwerp is de document.cookie API niet beschikbaar gesteld aan servicemedewerkers . De Cookie Store API is asynchroon en is daarom toegestaan ​​in servicewerknemers.

Interactie met de cookies werkt op dezelfde manier in documentcontexten en bij servicemedewerkers.

// Works in documents and service workers.
async function logOut() {
  await cookieStore.delete('session_id');
}

Het observeren van cookiewijzigingen is echter een beetje anders bij servicemedewerkers. Het wakker maken van een servicemedewerker kan behoorlijk duur zijn, dus we moeten expliciet beschrijven in welke cookiewijzigingen de medewerker geïnteresseerd is.

In het onderstaande voorbeeld controleert een toepassing die IndexedDB gebruikt om gebruikersgegevens in de cache op te slaan, wijzigingen in de sessiecookie en verwijdert de in de cache opgeslagen gegevens wanneer de gebruiker zich afmeldt.

// Specify the cookie changes we're interested in during the install event.
self.addEventListener('install', event => {
  event.waitUntil(cookieStore.subscribeToChanges([{name: 'session_id'}]));
});

// Delete cached data when the user logs out.
self.addEventListener('cookiechange', event => {
  for (const cookie of event.deleted) {
    if (cookie.name === 'session_id') {
      indexedDB.deleteDatabase('user_cache');
      break;
    }
  }
});

Beste praktijken

Binnenkort beschikbaar.

Feedback

Als je deze API eens probeert, laat ons dan weten wat je ervan vindt! Stuur feedback over de API-vorm naar de specificatierepository en rapporteer implementatiefouten via de Blink>Storage>CookiesAPI Blink-component.

We zijn vooral geïnteresseerd in prestatiemetingen en gebruiksscenario's die verder gaan dan degene die in de uitleg worden beschreven.

Aanvullende bronnen