4.4Créer une API REST & authentification JWT
L'essentiel en 30 secondes
- REST = ressources + méthodes :
GET /api/produits(lister, 200),POST(créer, 201),PUT(modifier),DELETE(supprimer) — JSON partout. - JWT = jeton signé auto-porteur : émis à la connexion, renvoyé dans
Authorization: Bearer …, vérifié sans session — adapté au front séparé et au mobile. - Réflexe de Riad : secret JWT en variable d'environnement (
.env, jamais en dur), HTTPS indispensable, validation + erreurs JSON propres.
Mini-cas filé — Riad ouvre son catalogue en API
La boutique de Riad veut une application mobile à Constantine : son catalogue doit sortir en JSON, pas en HTML. Riad conçoit ses endpoints (GET lister/lire, POST créer en 201, PUT, DELETE), renvoie du JSON avec les bons codes, puis sécurise : à la connexion il émet un JWT signé dont le secret vit en .env, et chaque requête mobile le renvoie en en-tête Authorization. Quand le jeton manque ou est falsifié, l'API répond 401 sans exposer les données. Quatrième jalon du fil rouge : le même back-end sert le site et le mobile.
Suite du cas 4.1-4.3 — Riad découple son back-end de ses clients.
1. L'API REST
Une API expose des DONNÉES (JSON) à d'autres programmes : front JavaScript séparé (React, Vue), application mobile, autres services. Le style REST : des ressources via des URL claires, manipulées par les méthodes HTTP selon leur sémantique — GET /api/produits (lister), GET /api/produits/{id} (lire), POST /api/produits (créer, 201), PUT/PATCH /api/produits/{id} (modifier), DELETE /api/produits/{id} (supprimer) — réponses JSON avec les bons codes (200, 201, 400, 401, 404). En PHP on peut bricoler à la main (router, json_encode, en-têtes, codes) mais en réel on utilise les outils d'API des frameworks (routage d'API, sérialisation, validation).
2. L'authentification par jetons (JWT)
HTTP est sans état et l'API sert des clients variés (pas de cookies navigateur garantis) : on s'authentifie par jetons. Le JWT (JSON Web Token) : après connexion réussie, le serveur émet un jeton SIGNÉ cryptographiquement (qui prouve l'identité sans être falsifiable) ; le client le stocke et le renvoie à chaque requête (Authorization: Bearer <jeton>) ; le serveur VÉRIFIE la signature — sans stocker de session, d'où « auto-porteur ». Idéal pour front séparé, mobile, multi-serveurs. Les frameworks offrent des systèmes d'auth d'API robustes (ne pas bricoler sa crypto en prod).
Sécurité d'API non négociable : jetons sûrs à durée courte, HTTPS indispensable (les jetons circulent), validation des entrées, autorisation (les droits, pas seulement l'identité), erreurs JSON cohérentes (codes + messages, sans fuites), rate limiting. Une API bien conçue est prévisible, professionnelle et sûre — le livrable des architectures back-end + front/mobile découplés.
Le 200 universel (scène à ne pas reproduire)
Moralité : 201 quand c'est créé, 404 quand c'est absent, 400 quand c'est invalide — le JSON dit quoi, le code dit comment.
🔎 Exemple concret — 🔎 Exemple concret — Les endpoints du catalogue de Riad
La table que Riad affiche au-dessus de son écran :
GET /api/produits → lister (200)
GET /api/produits/{id} → lire (200, 404 si absent)
POST /api/produits → créer (201, 400 si invalide)
PUT /api/produits/{id} → modifier (200, 404 si absent)
DELETE /api/produits/{id} → supprimer (204)
Auth → Authorization: Bearer (401 si absent/invalide)
Lecture : cinq lignes, cinq couples méthode + URL + code.
Leçon : l'action vient de la méthode, la preuve d'identité du jeton.
Vocabulaire de la section
- API REST
- Interface exposant des données (JSON) à d'autres programmes (front, mobile, services) ; ressources via URL, méthodes HTTP sémantiques, codes de statut.
Exemple simple : Le catalogue JSON de Riad sert le site et l'application mobile.
Ce que ce n'est pas : une page HTML générée côté serveur uniquement.
Réflexe : ressource + méthode + code attendu pour chaque endpoint.
- Ressources & méthodes (API)
- GET lister/lire, POST créer (201), PUT/PATCH modifier, DELETE supprimer ; JSON avec les bons codes (200, 201, 400, 401, 404…).
Exemple simple : Riad crée en POST → 201, lit un absent → 404.
Ce que ce n'est pas : tout en POST avec 200 même en erreur.
Réflexe : jamais 200 pour une erreur, jamais de verbe dans l'URL.
- Authentification par jetons
- Pour les API (sans état, clients variés) : après connexion, jeton renvoyé à chaque requête (Authorization) et vérifié par le serveur.
Exemple simple : Le mobile de Riad renvoie son jeton à chaque appel catalogue.
Ce que ce n'est pas : une session cookie supposée disponible partout.
Réflexe : chaque route sensible exige et vérifie le jeton.
- JWT (JSON Web Token)
- Jeton SIGNÉ cryptographiquement, auto-porteur (sans stockage serveur), renvoyé à chaque requête et vérifié. Adapté au front séparé et au mobile.
Exemple simple : Riad émet un JWT à la connexion et vérifie sa signature ensuite.
Ce que ce n'est pas : un identifiant prévisible passé en query string.
Réflexe : signature vérifiée, durée courte, rien de sensible dedans.
- Sécurité d'API
- Jetons sûrs, HTTPS indispensable, validation des entrées, autorisation (droits), erreurs JSON propres, rate limiting.
Exemple simple : Riad cumule HTTPS + validation + 401/403 propres + limite de débit.
Ce que ce n'est pas : une API sans HTTPS qui accepte tout et répond 200.
Réflexe : le jeton circule : il doit voyager chiffré et expirer vite.
En pratique — En pratique — Exposer des données via une API REST
- Concevez les endpoints d'une ressource selon REST : GET lister/lire, POST créer (201), PUT modifier, DELETE supprimer — réponses JSON.
- Renvoyez du JSON avec les bons codes (json_encode + en-têtes à la main, ou outils d'API d'un framework).
- Sécurisez par JWT : jeton signé émis à la connexion (secret en .env), vérifié à chaque requête (Authorization).
- Ajoutez HTTPS, validation, autorisation, erreurs JSON cohérentes et rate limiting.
Script prêt à dire — présenter son API au client mobile (30 s)
« C'est Riad : notre API expose le catalogue en JSON — GET pour lire, POST en 201 pour créer, PUT et DELETE, avec les bons codes. La connexion émet un JWT signé dont le secret vit en .env, chaque requête l'envoie en Authorization, et tout circule en HTTPS. »
À dire en démo ; montrez la table des endpoints et un appel avec jeton.
Modèle copier-coller — API PHP + JWT via l'environnement (code testé)
'Configuration serveur manquante']); exit; }
header('Content-Type: application/json');
$methode = $_SERVER['REQUEST_METHOD'];
$chemin = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
// Connexion : vérifie (hachage en réel), émet un JWT court
if ($methode === 'POST' && $chemin === '/api/connexion') {
$corps = json_decode(file_get_contents('php://input'), true) ?? [];
if (empty($corps['email']) || empty($corps['motDePasse'])) {
http_response_code(400); echo json_encode(['erreur' => 'Email et mot de passe requis']); exit;
}
$jeton = JWT::encode(['sub' => $corps['email'], 'iat' => time(), 'exp' => time() + 3600], $secret, 'HS256');
echo json_encode(['jeton' => $jeton]); exit;
}
// Route protégée : vérifie le JWT (401 si absent/invalide)
if ($methode === 'GET' && $chemin === '/api/produits') {
$entete = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (!str_starts_with($entete, 'Bearer ')) { http_response_code(401); echo json_encode(['erreur' => 'Jeton manquant']); exit; }
try {
JWT::decode(substr($entete, 7), new Key($secret, 'HS256'));
} catch (Exception $e) { http_response_code(401); echo json_encode(['erreur' => 'Jeton invalide']); exit; }
echo json_encode([['nom' => 'Couscoussier', 'prix' => 2500]]); exit;
}
http_response_code(404); echo json_encode(['erreur' => 'Introuvable']);
Prototype local
Endpoints JSON à la main (router + json_encode) : conventions REST dès le début, elles ne coûtent rien.
Application réelle
Comme Riad : outils d'API du framework, JWT via .env, HTTPS, validation et rate limiting.
API multi-clients
Un seul back-end pour web + mobile : versionnez (/api/v1/) pour évoluer sans casser.
Données sensibles
Durée de jeton courte, révocation prévue, rien de sensible dans le payload — et audit avant prod.
.env hors Git), jamais en dur dans le code ; HTTPS obligatoire (les jetons circulent en clair sinon) ; durée courte et validation systématique. Exemples avec données fictives uniquement — aucun secret réel. Contenu pédagogique, pas un audit de sécurité.✓ Bonnes pratiques
- Concevoir en ressources + méthodes + bons codes.
- Authentifier par JWT vérifié à chaque requête.
- Imposer HTTPS, validation et erreurs JSON propres.
✗ Pièges fréquents
- Tout renvoyer en 200 même en erreur.
- Exposer une API sans HTTPS.
- Bricoler sa crypto JWT en production.
Points clés à retenir
- API REST = DONNÉES JSON pour front/mobile/services : RESSOURCES via URL, MÉTHODES sémantiques, CODES justes.
- À la main (router, json_encode) ou via FRAMEWORK (routage d'API, sérialisation, validation).
- JWT : jeton SIGNÉ auto-porteur (Authorization: Bearer), vérifié sans session — adapté aux clients variés.
- SÉCURITÉ : secret en .env, HTTPS, validation, autorisation, erreurs propres, rate limiting.
Défi 48h — appliquez demain
Exposez 1 ressource en JSON (5 endpoints, bons codes) + connexion JWT (secret en .env) et vérifiez le 401 sans jeton.
- Je peux citer les 5 endpoints et leurs codes.
- Je sais expliquer JWT vs sessions.
- J'ai 1 route protégée testée avec et sans jeton.
Questions fréquentes
Pourquoi construire une API plutôt qu'un site qui génère du HTML ?
Quand le consommateur n'est pas un navigateur seul : application front séparée (React/Vue/Angular, SPA interactive), application mobile (qui ne consomme que du JSON), plusieurs clients (web + mobile + partenaires sur UN même back-end réutilisé), architectures de services/microservices. Sinon, le site classique (HTML serveur) reste plus simple. Riad choisit l'API dès qu'un mobile ou un front découplé entre en jeu.
Qu'est-ce qu'un JWT — et pourquoi des jetons plutôt que des sessions pour les API ?
Sessions : état côté serveur + cookies navigateur — bien pour un site classique, mais liées au navigateur et compliquées à l'échelle multi-serveurs. JWT : jeton signé émis à la connexion, stocké côté client, renvoyé en Authorization et vérifié par signature — sans état serveur, adapté aux clients variés (mobile, services) et au passage à l'échelle. Vigilances : clé protégée (jamais en dur), durée courte/refresh, rien de sensible dans le payload, HTTPS.
Pourquoi des jetons (JWT) plutôt que des sessions pour une API ?