Devine mon nombre - Client, serveur et HTTP
Objectifs
- Distinguer ce qui s'exécute côté client (navigateur) et côté serveur
- Observer et analyser des requêtes HTTP avec les outils de développement
- Comprendre ce qui est mémorisé côté client et ce qui l'est côté serveur
- Comparer les méthodes GET et POST et savoir quand les utiliser
- Comprendre pourquoi HTTPS est nécessaire pour protéger des données sensibles
Mise en place
Structure des fichiers
Crée le dossier suivant dans ton espace de travail :
serveur.py
from flask import Flask, request, jsonify, send_from_directory
import random
app = Flask(__name__) # ne pas chercher à comprendre cette ligne pour l'instant
NOMBRE_SECRET = random.randint(1, 100)
tentatives = 0
@app.route("/")
def accueil():
return send_from_directory("static", "index.html")
@app.route("/deviner")
def deviner():
global tentatives
proposition = request.args.get("proposition", "")
if not proposition.isdigit():
return jsonify({"resultat": "erreur", "message": "Entre un nombre entier."})
proposition = int(proposition)
tentatives += 1
if proposition < NOMBRE_SECRET:
message = "Trop petit !"
elif proposition > NOMBRE_SECRET:
message = "Trop grand !"
else:
message = f"Gagne en {tentatives} tentatives !"
return jsonify({"resultat": message, "tentatives": tentatives})
@app.route("/inscription", methods=["POST"])
def inscription():
pseudo = request.form.get("pseudo")
mdp = request.form.get("mot_de_passe")
return f"<p>Recu : pseudo={pseudo}, mot_de_passe={mdp}</p>"
app.run(debug=True)
static/index.html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Devine mon nombre</title>
</head>
<body>
<h1>Devine le nombre (entre 1 et 100)</h1>
<input type="number" id="proposition" min="1" max="100" placeholder="Ton nombre">
<button id="btn">Deviner</button>
<p id="resultat"></p>
<p id="historique"></p>
<h2>Creer un compte (simulation)</h2>
<form action="/inscription" method="POST">
<input type="text" name="pseudo" placeholder="Pseudo">
<input type="password" name="mot_de_passe" placeholder="Mot de passe">
<button type="submit">S'inscrire</button>
</form>
<script>
const historique = []; // memorise cote client
document.getElementById("btn").addEventListener("click", function () {
const valeur = document.getElementById("proposition").value;
fetch("/deviner?proposition=" + valeur)
.then(function (reponse) { return reponse.json(); })
.then(function (donnees) {
document.getElementById("resultat").textContent = donnees.resultat;
historique.push(valeur);
document.getElementById("historique").textContent =
"Tentatives : " + historique.join(", ");
});
});
</script>
</body>
</html>
Lancer le serveur
Dans le terminal de VSCode, installe Flask :
Puis exécute serveur.py directement depuis VSCode (bouton ▶ en haut à droite).
Ouvre ensuite http://localhost:5000 dans ton navigateur, puis ouvre les outils de développement (F12) et place-toi sur l'onglet Réseau.
Partie 1 - Observer les échanges entre client et serveur
Joue quelques tours : entre des nombres et clique sur « Deviner ».
Q1
Dans l'onglet Réseau, clique sur une des requêtes qui apparait. Recopie l'URL complète de la requête.
Q2
Comment s'appelle la partie de l'URL qui commence par ? ? Quel est le nom du paramètre transmis ? Quelle est sa valeur ?
Q3
Quelle méthode HTTP est utilisée ? (cherche dans les en-têtes de la requête)
Q4
Clique sur l'onglet Aperçu ou Réponse de cette requête. Que contient la réponse du serveur ? Sous quel format ?
Partie 2 - Client ou serveur ?
Q5
Complète le tableau suivant :
| Action | Côté client ou côté serveur ? |
|---|---|
| Afficher le message « Trop petit ! » dans la page | |
| Comparer la proposition au nombre secret | |
| Compter le nombre de tentatives | |
| Mettre à jour la liste des tentatives affichée |
Q6
Ouvre le fichier index.html et repère le tableau historique dans le code JavaScript.
- Est-ce que ce tableau est envoyé au serveur à chaque requête ?
- Est-ce que le serveur connait la liste de tes tentatives ?
- Où est-il mémorisé ?
Q7
Ouvre le fichier serveur.py et repère la variable tentatives.
- À quel moment est-elle modifiée ?
- Que se passe-t-il si tu fermes et relances le serveur en cours de partie ?
- Que se passe-t-il si deux élèves jouent en même temps sur le même serveur ?
Partie 3 - Modifier le comportement côté client
Ouvre index.html dans un éditeur de texte.
Q8
Repère la ligne suivante :
Que se passe-t-il quand l'utilisateur clique sur le bouton ? Dans quel ordre les actions sont-elles exécutées ?
Q9
Ajoute la ligne suivante juste après l'accolade ouvrante de la fonction :
Recharge la page, joue un tour, puis ouvre l'onglet Console des outils de développement. Que vois-tu ? Sur quelle machine ce code s'est-il exécuté ?
Q10
Modifie la requête pour envoyer la valeur 999 quel que soit ce que l'utilisateur a tapé. Comment le serveur réagit-il ? Que cela montre-t-il sur la confiance qu'on peut accorder aux données reçues côté serveur ?
Partie 4 - GET ou POST ? Confidentialité et chiffrement
Consulte le formulaire d'inscription en bas de la page.
Q11
Remplis le formulaire avec un pseudo et un mot de passe fictifs, puis clique sur « S'inscrire ». Dans l'onglet Réseau, la requête utilise-t-elle GET ou POST ?
Q12
Le mot de passe apparait-il dans l'URL ? Où peut-on le trouver malgré tout dans les outils de développement ?
Q13
Modifie temporairement le formulaire pour passer en method="GET". Que se passe-t-il avec le mot de passe dans l'URL ? Pourquoi est-ce problématique ?
Q14
L'adresse du serveur commence par http://. Est-ce que POST suffit à protéger le mot de passe d'un attaquant qui intercepterait le trafic réseau ? Justifie.
Q15
Quelle modification de l'adresse indiquerait que la transmission est chiffrée ? Comment le navigateur le signale-t-il visuellement ?
Bilan - Schéma à compléter
Complète le schéma suivant. Remplace chaque ___ par le terme qui convient.
sequenceDiagram
participant N as Navigateur (client)
participant S as Serveur (Python)
Note over N: 1. l'utilisateur clique<br/>le code ___ s'exécute
N->>S: 2. requête ___ vers /deviner<br/>paramètre : ___=___
Note over S: 3. le serveur ___<br/>la proposition au nombre secret
S-->>N: 4. réponse ___ : "___"
Note over N: 5. le code JS modifie le ___<br/>pour afficher le message
Pour aller plus loin
Extension 1
Comment empêcher un utilisateur de tricher en envoyant 999 depuis la console du navigateur ?
Extension 2
Que faudrait-il changer si on voulait que chaque élève joue avec son propre nombre secret, indépendamment des autres ?
Extension 3
Cherche ce qu'est un cookie. Comment pourrait-il résoudre le problème de la question précédente ?