Ludovic Frank - Développeur indépendant

Les échanges signés, quand Google devient votre CDN (enfin, presque…)

ionicons-v5-k Ludovic Frank 14 mai 2024
590 lectures Niveau : Confirmé

Salut les petits loups 🙂 (ouaip, c'est la chaleur, ça me fait craquer... déso),

Merci d'avoir cliqué sur mon article 😁, comme d'habitude on va essayer de faire de la qualité et j'espère qu'il vous plaira...

Cette semaine, on va parler des échanges signés, c'est une techno encore peu connue et pourtant je trouve ça super intéressant, donc on va partager tout ça avec vous !

Brièvement, qu'est-ce que permettent les échanges signés ?

Les échanges signés, c'est une technologie proposée par Google permettant de mettre vos pages et vos "assets” (tel que le CSS) en cache chez Google (et d'autres entreprises compatibles) et ça leur permet de faire précharger aux clients vos contenus, sans se les faire se connecter à vos serveurs.
Voilà, l'article est fini, bonne journée à tous 🤣 ! ... Mais non, on va aller plus loin.

Un peu de contexte

Nous sommes en janvier 2023, j'ai envie de bosser sur mon CMS pour changer un peu, l'améliorer et le rafraîchir un peu...

En me baladant un peu sur internet je tombe sur un article (je ne sais plus où, et en anglais), qui dit que dorénavant les échanges signés fonctionnent aussi avec la version "desktop" de Google...

"Les échanges quoi ? C'est quoi ce truc-là ?"

Je commence donc à m'intéresser à la technologie bien que je n'y attendais pas grand-chose, en fait à une époque, le SEO a commencé à me saouler quand Google a sorti les pages "AMP" (pour "Accelerated Mobile Page").
En gros, avec AMP, tout restait chez Google. Ce qui était un problème pour moi, le navigateur doit afficher l'URL réelle du contenu et non pas quelque chose commençant par le domaine de Google...

Je commence donc à creuser, à regarder le peu de ressource sur le sujet (article, vidéo), et en creusant je me dis que c'est quand même très intéressant et que j'aimerais bien le mettre en place sur mon site ainsi que celui des Frères Marchand.

Concrètement, comment ça marche ?

En fait, on créer un "paquet binaire", contenant une requête HTTP et sa réponse, par exemple la requête HTTP vous permettant de charger la page sur laquelle vous êtes actuellement et donc la réponse contenant les headers ainsi que le corps (dans notre cas le HTML) de la page.

Une fois ce paquet crée, on le signe avec la clef privée lié à un certificat (la clef publique) contenant le nom de domaine ainsi que l'attribut "CanSignHttpExchanges". Cette signature permet aux clients de vérifier que le paquet a bien été émis par l'éditeur réel de la ressource et n'a pas été altéré. Cela permettra au navigateur d'afficher votre domaine et votre URL dans la barre d'adresse, même si, techniquement là la ressource a été chargé depuis d'autres serveurs.

Comment mettre en place les échanges signés ?

En fait, pour mettre en place les échanges signés, vous devez mettre en place un "reverse proxy", devant votre serveur web, c'est lui qui interceptera les demandes de création d'un échange signé pour une ressource et qui créera cet échange signé, il vous faudra également créer un certificat (et sa clef privée) pour signer les échanges, quand j'ai fait ma recherche, seuls DigiCert et Google proposaient la vérification de ce type de certificat.

Pour le côté pratique, je vous conseille cette extension, compatible avec tous les navigateurs basé sur Chromium, elle vous permettra de vérifier qu'une page fonctionne correctement avec les échanges signés.

Les "reverse proxy” open source compatible

Tout d'abord, excusez-moi s’il y a des confusions et que tout n'est pas clair dans ce chapitre, en effet, la technologie étant jeune, c'est un peu compliqué d'avoir les bonnes informations au bon endroit...

Le module pour NGINX

Vous pouvez trouver ici, un module pour NGINX, ne l'ayant pas utilisé, je ne sais pas ce qu'il vaut, mais Google en parle dans sa documentation.

Le serveur HTTP "sxg-rs"

Retrouvez ici une implémentation en Rust d'un reverse proxy qui gère les échanges signés, ceci étant dit, soyez prudent, je n’ai pas trop le sentiment que chez Google ils mettent en avant ce projet-là...

Le web packager server

Hop là, par ici, une autre implémentation en Go, je suis plus confiance sur ce projet-là.

Cloudflare

Cloudflare propose l'activation des échanges signés à l'aide d'un simple bouton dans leur interface, cette option fait partie de leurs offres payantes.

Pour l'activer, ça se passe dans "Spped" > "Optimisation" > "Autres"

Pourquoi j'ai choisi Cloudflare en reverse proxy ?

Ils font partie des entreprises de "confiance" pour moi, ça fait 10 ans que je les connais (merci, Korben, à l'époque. D’ailleurs son blog utilise aussi les échanges signés) et ils n'ont jamais augmenté leurs prix, ni fait de chose réellement néfaste (à ma connaissance) malgré la puissance qu'ils ont maintenant, d'ailleurs, il est très facile de "sortir" de leurs services, un simple changement de DNS est c'est fini.

Moi, je voulais surexploité les échanges signés, mettre en cache le HTML c'est bien, mais le problème quand on charge une page web, c'est le CSS au-dessus de la ligne de flottaison, il bloque le rendu de la page... donc, il faut que celui-ci soit en cache...

J'avais donc le choix de soit utiliser du temps pour implémenter les reverse proxy proposé par Google dans mon infra, soit laisser Cloudflare faire et me focus sur l'expérience utilisateur, en regardant comment j'allais mettre en cache le HTML et le CSS.

J'ai fait le choix de faire confiance à Cloudflare et si ça ne va pas, le retour en arrière reste toujours possible.

Comment bien exploiter les échanges signés ?

Tout va se passer dans ce que renvoie votre serveur, notamment l'en-tête "Cache" qui va permettre à Google (ou autre partie tierce qui souhaite exploiter les échanges signés de votre site) de savoir comment gérer ça.

Déjà vous devez changer le "private" en "public", pour expliquer au CDN et à Google qu'ils peuvent garder cette ressource en cache.

Ensuite, vous devez définir le nombre de secondes pendant lesquels les caches partagés doivent garder la ressource en cache, ça c'est via la variable "s-maxage" que cela se passe.

Dans un projet Symfony, voilà comment vous pouvez faire :

Une fois que vous avez fait votre fonction qui ajout les bons headers ont une réponse, il ne vous reste plus qu'a créé un "Listener", qui va vérifier s'il doit modifier la réponse et si doit le faire alors il appelle notre fonction créer précédemment.

Ici on voit la variable "ROUTE_TO_CDN_CACHE" ce sont les routes Symfony que vous souhaitez passer en "public".

Ah bah oui hein... imaginez vos utilisateurs qui viennent de Google et qu'ils voient une page générique, sans leur joli nom d'utilisateur en haut à droite et pour une boutique sans leur panier... c'est pas top.

Google propose d'utiliser l'en-tête "Vary: Cookie" pour dire au navigateur de ne pas utiliser l'échange signé et charger la page depuis le serveur normalement quand le navigateur à un cookie enregistre pour ce domaine.

Ouais, mais moi je n’aime pas, ce n’est pas une bonne expérience utilisateur... c'est nase, on veut quand même profiter de temps de chargement ultra rapide..

Pour la fromagerie en ligne des Frères Marchand, je voulais aussi les échanges signés, alors comment j'ai fait ?
Très simple, toutes les pages produits, l'accueil, les catégories, on les met en "public" avec le code que je vous ai donné précédemment (j'ai extrait ce code de là d'ailleurs), on utilise Varnish pour nettoyer tous les cookies envoyés par le client au serveur afin d'éviter toute fuite de donnée.

Une fois la page chargée, on fait une seconde requête HTTP avec Fetch, cette requête regarde si on est connecté, si oui, on remplace les parties qui changent sur la page... dans notre cas, l'espace utilisateur et le panier.

Enfin, on créer un cache local avec le "localStorage", pour garder les réponses de cette requête, pour les changements de page...

Voilàààààà, là on exploite les échanges signés comme il faut... et tout le monde obtient une bonne expérience utilisateur 😍

Utiliser les échanges signés avec le fichier CSS

Mettre en cache le HTML chez Google, c'est bien... mais nous, on veut un chargement instantané, il est hors de question que l'utilisateur patiente pendant le téléchargement et l'interprétation du CSS pour voir la page.

Pour ça avec le reverse proxy de Cloudflare, il suffit d'ajouter un header HTTP à vos réponses, utilisez l'en tête "link”, pour dire au navigateur de précharger une ressource.

 

Cloudflare se chargera de modifier l'échange signé généré pour votre HTML en y ajoutant un lien vers un autre échange signé, celui du CSS.

Ici, je me base sur Cloudflare, mais dans le protocole, il est bien signifié qu'il est possible de créer des échanges signés liés, j'imagine donc que les autres implémentations sont compatibles (mais qu’il faut faire autrement).

Vérifier que l'échange signé fonctionne correctement

Pour ça il vous faut simplement votre navigateur basé sur Chromium et Google...

Une fois vos échanges signés mis en place, vous pourrez voir dans l'onglet "network" de votre navigateur que directement depuis Google, il charge vos ressources, avant même que l'utilisateur ne clique sur votre site, pour rappel, ça ne créera pas de connexion vers vos serveurs (pour des raisons de confidentialité).

Conclusion

Et voilà, cet article touche à sa fin, j'espère qu'il vous a plu et vous a appris quelque chose.
Passez une très bonne semaine et à très vite 😁.