HTTP est un protocole sans mémoire. Chaque requête que ton navigateur envoie est traitée de façon indépendante, sans lien avec celle d'avant. Pourtant, les applis web "se souviennent" que tu es connecté d'une page à l'autre. Ce petit tour de passe-passe mérite qu'on l'ouvre.
Le problème : HTTP est stateless
Quand tu remplis un formulaire de connexion et que tu cliques sur "Se connecter", ton navigateur envoie un POST /login avec ton email et ton mot de passe. Le serveur vérifie, c'est bon. Il répond 200 OK.
Puis tu navigues vers /profil. Nouvelle requête. Le serveur ne sait absolument pas qui tu es : il n'y a pas de mémoire entre les deux échanges. C'est ça, le stateless : chaque requête repart de zéro.
Il faut donc un mécanisme pour transporter une preuve d'identité d'une requête à l'autre. Deux solutions dominent aujourd'hui.
Solution 1 : sessions côté serveur
Le serveur crée un identifiant de session après un login réussi, le stocke en base, et l'envoie au navigateur via un cookie.
Le flow complet :
Flow login avec cookie de session.
À chaque requête, le navigateur renvoie automatiquement le cookie. Le serveur retrouve l'utilisateur via un SELECT sur la table sessions. Pour terminer la session, il suffit de supprimer la ligne en base : la révocation est immédiate.
Solution 2 : tokens JWT
Un JWT (JSON Web Token) est un jeton signé que le serveur crée au moment du login et renvoie au client. Il contient les informations de l'utilisateur directement dans le token, sans stockage côté serveur.
Structure d'un JWT : trois parties encodées en base64, séparées par des points.
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0MiwiZXhwIjoxNzUwMDAwMDAwfQ.signature
[header] [payload] [signature]Le payload est lisible par n'importe qui (base64, pas chiffré). Mais la signature HMAC ou RSA garantit qu'il n'a pas été modifié : si tu changes user_id dans le payload, la signature ne correspond plus et le serveur rejette le token.
Le navigateur stocke le JWT et l'envoie dans l'en-tête de chaque requête :
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0Mn0.signatureLe serveur vérifie la signature et lit le payload. Pas de SELECT en base, pas d'état côté serveur.
Sessions vs JWT : le comparatif
| Critère | Sessions (cookie) | JWT (token) |
|---|---|---|
| Stockage serveur | Oui (table sessions) | Non |
| Révocation immédiate | Oui (DELETE en base) | Difficile (attendre l'expiration) |
| Lookup base à chaque requête | Oui | Non |
| Scaling horizontal | Nécessite un store partagé | Natif (stateless) |
| Taille du cookie/header | Petite (sid ~32 chars) | Plus grande (payload encodé) |
| Adapté pour | Apps monolithiques, admin | APIs, microservices, mobile |
Pourquoi cookie httpOnly, pas localStorage ?
Un JWT dans localStorage est accessible par tout script JavaScript qui s'exécute sur ta page. Si une dépendance npm compromise ou une XSS (Cross-Site Scripting) s'invite dans ta page, elle peut lire le token et se faire passer pour toi.
Un cookie HttpOnly ne peut pas être lu par JavaScript. Il est transmis automatiquement par le navigateur, mais jamais exposé à document.cookie ni à window.localStorage. Le flag Secure garantit qu'il ne circule que sur HTTPS, et SameSite=Lax protège contre les attaques CSRF les plus courantes.
Set-Cookie: token=eyJ...; HttpOnly; Secure; SameSite=Lax; Max-Age=3600Magic link : l'auth sans mot de passe
C'est le mécanisme qu'utilise Supabase par défaut, ainsi que Notion et Slack.
- L'utilisateur entre son email.
- Le serveur génère un token signé à usage unique, avec une expiration courte (15 min chez Supabase, parfois 10 min ou 1 h selon le service).
- Ce token est envoyé dans un email sous forme d'un lien :
https://mon-site.com/auth/verify?token=xyz. - L'utilisateur clique, le serveur valide la signature, crée une session ou un JWT, et redirige.
Avantage principal : aucun mot de passe à stocker, donc aucun mot de passe à compromettre. La surface d'attaque se réduit à la messagerie de l'utilisateur.
OAuth : "se connecter avec Google"
OAuth 2.0 est un protocole de délégation d'authentification. Plutôt que de gérer les mots de passe toi-même, tu délègues à un fournisseur de confiance (Google, GitHub, Apple).
Quand l'utilisateur clique sur "Continuer avec Google" : Google vérifie son identité, puis renvoie un token signé à ton serveur. Ton serveur l'échange contre un token d'accès, crée ou retrouve le compte de l'utilisateur dans ta base, puis émet une session ou un JWT habituel. Tu n'as jamais vu le mot de passe.