La cantine du lycée met en ligne un formulaire de réservation
Exercice de TD · niveau 3 (difficile) · NSI (première), chapitre 10 — Interagir sur le Web · Client, serveur, GET et POST
Énoncé
La cantine du lycée met en ligne un formulaire de réservation :
<form method="get" action="/commander">
<select name="plat">...</select>
<button type="submit">Commander</button>
</form>
Le serveur enregistre la commande et débite le compte de l'élève.
- Décrire trois situations ordinaires — sans aucune malveillance — où l'élève est débité deux fois.
- Le développeur passe en POST. Lesquelles de ces trois situations disparaissent ?
- POST suffit-il ? Proposer une solution complète.
Corrigé
1. Trois situations, toutes involontaires :
- l'élève trouve la page lente, actualise (touche F5) : le navigateur rejoue la même requête GET, une deuxième commande part ;
- il met la page de confirmation en favori, et y revient le lendemain « pour vérifier sa commande » : l'URL contient tous les paramètres, la commande est repassée ;
- le navigateur, un antivirus ou un aperçu de lien pré-charge l'adresse pour gagner du temps. Personne n'a cliqué, et la commande est partie.
La cause est unique et porte un nom : une requête GET est censée être idempotente — la rejouer doit laisser le monde dans le même état. Ici, elle débite un compte. Toute l'infrastructure du Web, du bouton « actualiser » aux caches en passant par les robots d'indexation, est bâtie sur cette hypothèse ; un GET qui modifie la trahit.
2. Les deux dernières disparaissent : un POST ne se met pas en favori (l'URL ne porte pas les données), et rien ne pré-charge un POST. La première subsiste : actualiser une page obtenue par POST est possible — le navigateur affiche seulement un avertissement « voulez-vous renvoyer les données ? », que l'on valide sans lire.
3. Non, POST ne suffit pas. Deux mesures s'ajoutent :
- Redirection après envoi. Le serveur répond au POST par une redirection (
303) vers une page de confirmation en GET. L'élève se retrouve sur une adresse actualisable sans risque, et le POST n'est plus la dernière requête de l'historique. - Un jeton à usage unique. Le formulaire contient un champ caché portant une valeur imprévisible ; le serveur la note comme consommée à la première réception et ignore les suivantes. C'est la seule mesure qui protège vraiment, parce qu'elle est côté serveur : elle résiste même à une requête forgée à la main.
Contrôle : avec le jeton, rejouer deux fois exactement la même requête POST ne débite qu'une fois. C'est bien la propriété qu'on voulait, et on l'a obtenue là où elle est vérifiable.
Piège : croire que le problème vient du choix GET/POST. Il vient de ce que l'effet est décidé par une requête que n'importe quoi peut rejouer. POST déplace la difficulté, le jeton la supprime.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.