Jetons JWT en PHP : Guide complet de mise en œuvre
\n\nJWT (JSON Web Token) est un standard ouvert (RFC 7519) pour la création de jetons d'accès basés sur le format JSON. En PHP, JWT est largement utilisé pour implémenter l'authentification sans état (stateless authentication) dans les API REST, les applications monopages (SPA) et les microservices.
\n\nDans cet article, nous allons détailler comment travailler avec les jetons JWT en PHP : de l'installation de la bibliothèque à la création, la vérification et l'actualisation des jetons.
\n\nQu'est-ce que JWT et pourquoi en a-t-on besoin ?
\n\nJWT se compose de trois parties séparées par des points :
\n\n- \n
- Header (en-tête) — contient le type de jeton (JWT) et l'algorithme de signature (par exemple, HS256 ou RS256). \n
- Payload (charge utile) — contient les revendications (claims) : identifiant utilisateur, rôle, heure d'émission (iat), date d'expiration (exp) et autres données. \n
- Signature (signature) — créée en hachant l'en-tête et la charge utile à l'aide d'une clé secrète. \n
Principaux avantages de JWT :
\n- \n
- Ne nécessite pas de stockage de sessions sur le serveur (stateless). \n
- Peut contenir n'importe quelles données (par exemple, le rôle de l'utilisateur). \n
- Fonctionne avec différents domaines et applications mobiles. \n
- Se vérifie facilement sans accès à la base de données. \n
Installation de la bibliothèque firebase/php-jwt
\n\nPour travailler avec JWT en PHP, nous utiliserons la bibliothèque populaire firebase/php-jwt. L'installation se fait via Composer :
composer require firebase/php-jwt\n\nAprès l'installation, l'autoloading Composer apparaîtra dans le projet, qu'il faut inclure :
\n\nrequire_once 'vendor/autoload.php';\n\nuse Firebase\\JWT\\JWT;\nuse Firebase\\JWT\\Key;\n\nCréation d'un jeton JWT
\n\nPour créer un jeton, il faut définir une clé secrète ($secretKey) et former le payload. Exemple :
use Firebase\\JWT\\JWT;\n\n$secretKey = 'your-256-bit-secret-key-here';\n$issuedAt = time();\n$expirationTime = $issuedAt + 3600; // le jeton vit 1 heure\n\n$payload = [\n 'iss' => 'pythonlib.ru', // émetteur\n 'iat' => $issuedAt, // heure d'émission\n 'exp' => $expirationTime, // date d'expiration\n 'sub' => 123, // identifiant utilisateur\n 'role' => 'admin' // données personnalisées\n];\n\n$jwt = JWT::encode($payload, $secretKey, 'HS256');\necho $jwt;\n\nLe résultat sera une chaîne de la forme : eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJweXRob25saWIucnUiLCJpYXQiOjE3Mjg0MDAwMDAsImV4cCI6MTcyODQwMzYwMCwic3ViIjoxMjMsInJvbGUiOiJhZG1pbiJ9.signature
Vérification et décodage de JWT
\n\nLors de la réception d'un jeton du client (par exemple, depuis l'en-tête Authorization: Bearer <token>), il faut le vérifier :
use Firebase\\JWT\\JWT;\nuse Firebase\\JWT\\Key;\n\n$secretKey = 'your-256-bit-secret-key-here';\n$jwt = $_SERVER['HTTP_AUTHORIZATION'] ?? '';\n\ntry {\n $decoded = JWT::decode($jwt, new Key($secretKey, 'HS256'));\n $userId = $decoded->sub;\n $role = $decoded->role;\n \n echo "Utilisateur #{$userId} avec le rôle {$role} est autorisé.";\n} catch (\\Exception $e) {\n http_response_code(401);\n echo "Erreur : " . $e->getMessage();\n}\n\nImportant : la bibliothèque vérifie automatiquement la date d'expiration du jeton (exp) et l'heure d'émission (iat). Si le jeton a expiré ou est invalide, une exception sera levée.
\n\nActualisation de JWT (Refresh Token)
\n\nPour améliorer la sécurité, les JWT sont généralement rendus à courte durée de vie (15 à 60 minutes). Pour une session longue, on utilise un Refresh Token — un jeton séparé stocké dans la base de données qui permet d'obtenir un nouvel Access Token sans ressaisir le login/mot de passe.
\n\nExemple d'implémentation du refresh :
\n\nfunction refreshAccessToken(string $ref