Leçon 6/8 10 min

Stateless, cookies et sessions

HTTP n'a aucune mémoire. Le cookie, c'est le navigateur qui rappelle au serveur qui tu es à chaque requête.

Le facteur ne se souvient pas de la lettre d'hier

Reprends la métaphore du courrier qui traverse ce cours. Le facteur livre ta lettre, repart, et le lendemain il revient. Mais il ne se souvient de rien. Pour lui, chaque tournée est la première. Il ne sait pas qu'il t'a déjà parlé hier, ni ce que tu lui as dit.

HTTP fonctionne exactement comme ce facteur. Le mot savant, c'est stateless : sans état, sans mémoire. Chaque requête arrive orpheline. Le serveur la traite, répond, et oublie tout. La requête suivante repart de zéro, comme si vous ne vous étiez jamais croisés.

À la leçon 5, on a lu une requête brute et tu as vu passer une ligne mystérieuse : Cookie: session=abc123. On avait dit « on y reviendra ». C'est maintenant. Cette ligne est la réponse à une question qui paraît évidente mais qui ne l'est pas du tout : si le serveur n'a aucune mémoire, comment peux-tu rester connecté à ta boutique ?

Prédis avant de lire

Tu es connecté à ta boutique en ligne. Tu recharges la page de ton compte. Le serveur, qui n'a aucune mémoire de la requête précédente, sait quand même que c'est encore toi. Comment fait-il ?

Voir la réponse

Il ne le « sait » pas. C'est ton navigateur qui le lui re-dit. À chaque requête vers ce domaine, ton navigateur ré-attache tout seul un petit jeton, le cookie. Le serveur lit ce jeton et retrouve qui tu es. Sans ce rappel automatique, le serveur te traiterait comme un parfait inconnu à chaque clic. Le serveur ne te reconnaît jamais ; ton navigateur lui rafraîchit la mémoire en permanence.

Le mécanisme, pas à pas : le badge et le casier

Voici comment ta connexion tient debout, étape par étape. Garde deux images en tête : un badge (le cookie) et un casier (la session). Le badge ne contient pas tes affaires, juste un numéro. Tes affaires sont dans le casier, côté serveur.

  1. Tu te connectes. Ton navigateur envoie un POST /login avec ton email et ton mot de passe.
  2. Le serveur crée un casier. Il vérifie tes identifiants, puis ouvre une session de son côté : un casier avec un numéro, par exemple abc123, qui contient tes données (qui tu es, ton panier, tes droits).
  3. Le serveur te tend le badge. Sa réponse contient un en-tête Set-Cookie: session=abc123. C'est le numéro du casier, pas son contenu.
  4. Le navigateur range le badge. Il stocke ce cookie et le garde pour le domaine de la boutique.
  5. À chaque requête suivante vers ce domaine, le navigateur ajoute tout seul la ligne Cookie: session=abc123. Tu n'as rien à faire : c'est automatique.
  6. Le serveur ouvre le bon casier. Il lit abc123, va chercher le casier correspondant, et « te reconnaît ». En vrai, il ne t'a pas reconnu : il a juste relu le numéro que ton navigateur lui a re-tendu.

Le badge ne contient pas tes données. Le cookie de session transporte un simple numéro de casier. C'est voulu : un identifiant court voyage à chaque requête sans alourdir le trafic, et tes vraies données restent au chaud côté serveur. La session, c'est le casier ; le cookie, c'est juste le ticket pour l'ouvrir.

Deux requêtes : sans badge, puis avec

Le même navigateur, le même serveur, deux requêtes. La première arrive sans badge : le serveur ne sait pas qui parle. La seconde porte le badge : le serveur ouvre le casier et te salue. Rien n'a changé côté serveur ; tout tient à ce que le navigateur ré-attache.

Deux colonnes, navigateur à gauche, serveur à droite. Première requête GET /mon-compte sans cookie : le serveur répond « 401, qui êtes-vous ? ». Deuxième requête GET /mon-compte avec l'en-tête Cookie session=abc123 : le serveur ouvre le casier abc123 et répond « 200, bonjour Sam ». Ton navigateur Le serveur sans badge GET /mon-compte 401 · qui êtes-vous ? avec badge GET /mon-compte Cookie: session=abc123 ouvre le casier abc123 200 · bonjour Sam Le serveur n'a rien retenu : c'est le badge qui a parlé.
Deux requêtes identiques. La seule différence, c'est l'en-tête Cookie que ton navigateur ajoute tout seul.

À toi : prouver que le serveur n'a pas de mémoire

Un terminal simulé. On va faire à la main ce que ton navigateur fait tout seul. La différence cruciale : curl ne renvoie PAS les cookies automatiquement, contrairement au navigateur. Tu vas donc voir la misconception en vrai : même après un login réussi, la requête suivante repart inconnue, tant que tu ne renvoies pas le badge toi-même.

🖥️ Terminal simulé · le serveur ne te reconnaît pas tout seul
$

Les attributs du badge, en une phrase chacun

Tu as peut-être remarqué, dans le labo, que le Set-Cookie ne s'arrêtait pas à session=abc123. Il portait aussi HttpOnly et Secure. Ce sont des attributs qui encadrent le badge. Voici les trois essentiels, une phrase chacun :

  • HttpOnly : le JavaScript de la page ne peut pas lire ce cookie.
  • Secure : le navigateur ne l'envoie que sur une connexion HTTPS, jamais en clair.
  • SameSite : le navigateur ne joint pas ce cookie quand la requête part depuis un autre site.

Le pourquoi détaillé est au cours Sécurité. Ici, retiens juste leur existence et leur effet. Ces trois attributs servent à se défendre contre des attaques précises (vol de session, falsification de requête entre sites). Le « comment » et le « contre quoi », en profondeur, t'attendent dans le cours Sécurité, aux leçons sessions et cookies et CSRF.

Et côté code, c'est juste deux lignes

Tout ce ballet (créer le casier, tendre le badge, le relire à chaque fois) est tellement courant que les langages l'ont automatisé. En PHP, par exemple, session_start() gère le cookie et le casier pour toi, et tu lis ou écris tes données dans $_SESSION. La magie de « rester connecté » a un mécanisme bien concret, détaillé au cours PHP, leçon sessions et cookies.

The postman doesn't remember yesterday's letter

Pick up the mail metaphor running through this course. The postman delivers your letter, leaves, and comes back the next day. But he remembers nothing. To him, every round is the first. He doesn't know he already spoke to you yesterday, nor what you told him.

HTTP works exactly like that postman. The technical word is stateless: no state, no memory. Every request arrives an orphan. The server handles it, replies, and forgets everything. The next request starts from scratch, as if you'd never met.

In lesson 5, we read a raw request and you saw a mysterious line go by: Cookie: session=abc123. We said "we'll come back to it". Now is the time. That line answers a question that seems obvious but really isn't: if the server has no memory, how can you stay logged into your shop?

Predict before reading on

You're logged into your online shop. You reload your account page. The server, which has no memory of the previous request, still knows it's still you. How does it manage that?

Show the answer

It doesn't "know". Your browser tells it again. On every request to that domain, your browser re-attaches a small token all by itself, the cookie. The server reads that token and finds out who you are. Without that automatic reminder, the server would treat you as a total stranger on every click. The server never recognises you; your browser keeps refreshing its memory.

The mechanism, step by step: the badge and the locker

Here's how your session stays standing, step by step. Keep two images in mind: a badge (the cookie) and a locker (the session). The badge holds none of your belongings, just a number. Your belongings are in the locker, on the server side.

  1. You log in. Your browser sends a POST /login with your email and password.
  2. The server creates a locker. It checks your credentials, then opens a session on its side: a locker with a number, say abc123, holding your data (who you are, your cart, your rights).
  3. The server hands you the badge. Its response carries a header Set-Cookie: session=abc123. That's the locker's number, not its contents.
  4. The browser stores the badge. It keeps that cookie for the shop's domain.
  5. On every following request to that domain, the browser adds the line Cookie: session=abc123 all on its own. You do nothing: it's automatic.
  6. The server opens the right locker. It reads abc123, fetches the matching locker, and "recognises you". In truth it didn't recognise you: it just re-read the number your browser handed back.

The badge holds none of your data. The session cookie carries a plain locker number. That's deliberate: a short identifier travels on every request without bloating traffic, and your real data stays safe on the server. The session is the locker; the cookie is just the ticket to open it.

Two requests: without the badge, then with

The same browser, the same server, two requests. The first arrives without a badge: the server doesn't know who's speaking. The second carries the badge: the server opens the locker and greets you. Nothing changed on the server; it all hinges on what the browser re-attaches.

Two columns, browser on the left, server on the right. First request GET /my-account with no cookie: the server replies "401, who are you?". Second request GET /my-account with the header Cookie session=abc123: the server opens locker abc123 and replies "200, hello Sam". Your browser The server no badge GET /my-account 401 — who are you? with badge GET /my-account Cookie: session=abc123 opens locker abc123 200 — hello Sam The server kept nothing: the badge did the talking.
Two identical requests. The only difference is the Cookie header your browser adds on its own.

Your turn: prove the server has no memory

A simulated terminal. We'll do by hand what your browser does on its own. The crucial difference: curl does NOT send cookies back automatically, unlike the browser. So you'll see the misconception live: even after a successful login, the next request starts out as a stranger, until you send the badge back yourself.

🖥️ Simulated terminal · the server doesn't recognise you on its own
$

The badge's attributes, one sentence each

You may have noticed, in the lab, that the Set-Cookie didn't stop at session=abc123. It also carried HttpOnly and Secure. These are attributes that frame the badge. Here are the three essential ones, one sentence each:

  • HttpOnly: the page's JavaScript cannot read this cookie.
  • Secure: the browser only sends it over an HTTPS connection, never in the clear.
  • SameSite: the browser won't attach this cookie when the request comes from another site.

The detailed why is in the Security course. Here, just remember they exist and what they do. These three attributes defend against precise attacks (session theft, cross-site request forgery). The "how" and the "against what", in depth, await you in the Security course, in the sessions and cookies and CSRF lessons.

And in code, it's just two lines

This whole ballet (create the locker, hand out the badge, re-read it each time) is so common that languages have automated it. In PHP, for instance, session_start() handles the cookie and the locker for you, and you read or write your data in $_SESSION. The magic of "staying logged in" has a very concrete mechanism, detailed in the PHP course, in the sessions and cookies lesson.

🎯 Pratique

S'entraîner (clique pour ouvrir) :

💬 Ré-explique sans regarder
Ré-explique sans regarder

Explique à un collègue pourquoi on dit que HTTP est « stateless », et comment tu peux pourtant rester connecté à un site. Utilise les mots badge et casier.

Une bonne explication dit : HTTP est stateless, chaque requête arrive orpheline et le serveur ne garde aucune mémoire de la précédente. Pour rester connecté, le serveur crée un casier (la session) au login et te tend un badge (le cookie) avec Set-Cookie. Ton navigateur ré-attache ce badge avec Cookie: à chaque requête, tout seul. Le serveur ne te reconnaît jamais : il relit juste le numéro de casier que ton navigateur lui re-tend.
🧠 Rappel libre
Rappel libre

Sans remonter : quelle est la différence entre le cookie et la session, et qu'est-ce qui transite vraiment à chaque requête ?

La session est le casier côté serveur : il contient tes vraies données (qui tu es, ton panier, tes droits). Le cookie est le badge stocké par ton navigateur : il ne contient que le numéro du casier (ex. session=abc123). À chaque requête, c'est ce petit numéro qui transite dans l'en-tête Cookie:, pas tes données. Le serveur lit le numéro et va ouvrir le bon casier.
⚖️ Juge le code de l'IA
Accepter ou rejeter le code de l'IA

Tu demandes à l'IA de mémoriser les préférences de l'utilisateur (langue, thème, et son email pour le pré-remplir). Elle propose : « Je stocke tout dans le cookie en JSON, comme ça c'est simple, pas besoin de session côté serveur. » Tu acceptes, ou tu rejettes ?

À nuancer, plutôt à rejeter tel quel. Mettre langue et thème dans un cookie, c'est défendable : ce sont des préférences sans enjeu. Mais souviens-toi : le cookie repart à chaque requête vers le domaine. Plus tu y mets de données (surtout du JSON qui grossit), plus tu alourdis tout le trafic, et tu exposes ces infos (l'email) à chaque aller-retour. Le badge doit rester léger : un simple numéro de casier. Les vraies données, comme l'email, sont mieux dans le casier serveur (la session), qui ne voyage pas. Règle : le cookie identifie, la session stocke.
Que veut dire « HTTP est stateless » ?
Tu es connecté, tu recharges la page. Qui ajoute l'en-tête Cookie: session=abc123 à la requête ?
À quoi sert l'attribut HttpOnly sur un cookie de session ?
Ton cookie de session vaut session=abc123. Le contenu de ton panier (3 articles) est-il dedans ?
Prochaine étape

Le serveur n'a pas de mémoire, on l'a vu. Mais ton navigateur, lui, en a une autre sorte. Leçon 7 : le cache HTTP, ou comment ton navigateur évite de re-télécharger ce qui n'a pas changé, pour des pages qui s'affichent en un clin d'oeil.

Leçon 7 : Le cache HTTP →
Besoin d'un développeur pour votre projet ?

Réponse sous 24h · Sans engagement