Accès asynchrone aux cookies HTTP

Victor Costan

Qu'est-ce que l'API Cookie Store ?

L'API Cookie Store expose les cookies HTTP aux service workers et offre une alternative asynchrone à document.cookie. Grâce à l'API, plus simple à:

  • Évitez les à-coups sur le thread principal en accédant aux cookies de manière asynchrone.
  • Évitez d'interroger les cookies, car vous pouvez observer des modifications au niveau des cookies.
  • Accéder aux cookies des service workers

Lire la vidéo explicative

État actuel

Étape État
1. Créer une vidéo explicative Fin
2. Créer le brouillon initial de la spécification Fin
**3. Recueillir des commentaires et itérer sur les spécifications**. **En cours**
4. Phase d'évaluation En pause
5. Lancer Non démarré

Comment utiliser le magasin de cookies asynchrone ?

Activer la phase d'évaluation

Pour tester l'API en local, vous pouvez l'activer à partir de la ligne de commande:

chrome --enable-blink-features=CookieStore

La transmission de cet indicateur sur la ligne de commande active l'API de manière globale dans Chrome pour la session en cours.

Vous pouvez également activer #enable-experimental-web-platform-features dans chrome://flags.

Vous n'avez (probablement) pas besoin de cookies

Avant d'entrer dans le détail de la nouvelle API, j'aimerais préciser que les cookies la pire primitive de stockage côté client de la plate-forme. en dernier recours. Ce n'est pas un hasard : les cookies ont été les premiers cookies de stockage. Nous avons beaucoup appris depuis.

Les principales raisons d'éviter les cookies sont les suivantes:

  • Les cookies transfèrent votre schéma de stockage dans votre API backend. Chaque requête HTTP contient un instantané du cookie JAR. Cela permet aux utilisateurs aux ingénieurs back-end d’introduire des dépendances sur le format de cookie actuel. Une fois votre interface ne peut pas modifier son schéma de stockage sans déployer une modification correspondante sur le backend.

  • Les cookies ont un modèle de sécurité complexe. Les fonctionnalités modernes de la plate-forme Web suivent la même règle d'origine, ce qui signifie que chaque application dispose de son propre bac à sable, qui est complètement indépendant d'autres applications que l'utilisateur pourrait exécuter. Champs d'application des cookies la sécurité est bien plus complexe. Il s'agit simplement d'essayer pour résumer, cela doublerait la taille de cet article.

  • Les cookies ont un coût de performance élevé. Les navigateurs doivent inclure un instantané vos cookies dans chaque requête HTTP. Par conséquent, chaque modification apportée aux cookies propagées dans les piles de stockage et réseau. Les navigateurs récents ont une forte mais nous ne pourrons jamais faire des cookies aussi efficaces que les autres mécanismes de stockage, qui n'ont pas besoin à la pile réseau.

Pour toutes les raisons évoquées ci-dessus, les applications Web modernes doivent éviter les cookies et mais vous stockez un identifiant de session IndexedDB ajouter explicitement l'identifiant à l'en-tête ou au corps de requêtes HTTP spécifiques, via l'API fetch.

Ceci dit, vous êtes encore en train de lire cet article, car vous avez raison d'utiliser des cookies...

Le vénérable document.cookie L'API est une source d'à-coups assez garantie pour votre application. Par exemple, chaque fois que vous utilisez le getter document.cookie, le navigateur doit arrêter d'exécuter jusqu'à ce qu'il dispose des informations de cookie que vous avez demandées. Cela peut prendre saut de processus ou une lecture de disque, et entraînera des à-coups de votre UI.

Une solution simple à ce problème consiste à passer de document.cookie "getter" à l'API Cookie Store asynchrone.

await cookieStore.get('session_id');

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

Le setter document.cookie peut être remplacé de la même manière. À retenir que la modification ne sera appliquée qu'après l'affichage de la promesse cookieStore.set est résolu.

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

// undefined

Observer, ne pas sonder

Une application couramment utilisée pour accéder aux cookies à partir de JavaScript détecte les cas l'utilisateur se déconnecte et met à jour l'UI. Cela se fait actuellement en sondant document.cookie, qui introduit des à-coups et a un impact négatif sur la batterie vie.

L'API Cookie Store propose une autre méthode pour observer les cookies ce qui ne nécessite pas d'interrogation.

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

Bienvenue aux service workers

En raison de la conception synchrone, l'API document.cookie n'a pas été rendue disponibles pour service workers. L'API Cookie Store est asynchrone et peut donc être utilisée les nœuds de calcul.

L'interaction avec les cookies fonctionne de la même manière dans les contextes de document et dans de service workers.

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

Cependant, l'observation des modifications des cookies est un peu différente dans les service workers. Réveil un service worker peut s'avérer assez coûteux. Nous devons donc décrire explicitement les changements de cookie qui intéressent le nœud de calcul.

Dans l'exemple ci-dessous, une application qui met en cache les données utilisateur à l'aide de IndexedDB surveille les modifications apportées au cookie de session et supprime les données mises en cache lorsque le l'utilisateur se déconnecte.

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

Bonnes pratiques

Bientôt disponible.

Commentaires

N'hésitez pas à nous donner votre avis si vous essayez cette API. Veuillez rediriger des commentaires sur la forme de l'API dépôt de spécifications, et signaler les bugs d'implémentation Blink>Storage>CookiesAPI Composant Blink.

Nous sommes particulièrement intéressés par les mesures des performances et l'utilisation autres que ceux décrits dans l'explication.

Ressources supplémentaires