2
0

jwt.class.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. class jwt
  3. {
  4. private static $jwtToken;
  5. private static $jwtSecret = JWT_PRIVATE_KEY; // Clé secrète pour signer les tokens
  6. private static $jwtAlgorithm = "HS256"; // Algorithme utilisé pour signer le JWT (HS256)
  7. /**
  8. * Initialiser les configurations pour l'authentification
  9. */
  10. public static function init($loginUrl, $apiBaseUrl, $email, $password)
  11. {
  12. // Le JWT sera stocké dans cette propriété statique
  13. self::$jwtToken = null;
  14. }
  15. public static function checkSession()
  16. {
  17. // Vérifie si le JWT existe et n'est pas expiré
  18. if (self::$jwtToken && self::validateToken(self::$jwtToken)) {
  19. return json_encode(['authenticated' => true, 'token' => self::$jwtToken]);
  20. } else {
  21. return json_encode(['authenticated' => false]);
  22. }
  23. }
  24. /**
  25. * Authentifier l'utilisateur et récupérer le JWT
  26. */
  27. public static function authenticate(array $_input)
  28. {
  29. $user = user::authenticator($_input);
  30. if ($user["status"] == "success") {
  31. // Générer le JWT
  32. $user["token"] = self::generateToken($user);
  33. self::$jwtToken = $user["token"];
  34. return $user;
  35. } else {
  36. return FALSE;
  37. }
  38. }
  39. /**
  40. * Faire une requête API authentifiée avec le JWT
  41. */
  42. public static function makeAuthenticatedRequest($endpoint, $method = 'GET', $data = [])
  43. {
  44. if (!self::$jwtToken) {
  45. throw new Exception('Aucun jeton JWT disponible. Veuillez vous authentifier.');
  46. }
  47. // Vérification du token avant d'effectuer une requête
  48. if (!self::validateToken(self::$jwtToken)) {
  49. throw new Exception('Jeton JWT invalide ou expiré. Veuillez vous authentifier à nouveau.');
  50. }
  51. $ch = curl_init();
  52. $url = DOMAIN_API . $endpoint;
  53. curl_setopt($ch, CURLOPT_URL, $url . "/");
  54. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  55. // Ajouter le JWT dans l'en-tête d'autorisation
  56. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  57. 'Authorization: Bearer ' . self::$jwtToken,
  58. 'Content-Type: application/json'
  59. ]);
  60. // Configuration des méthodes GET/POST/PUT/DELETE
  61. if ($method === 'POST') {
  62. curl_setopt($ch, CURLOPT_POST, true);
  63. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  64. } elseif ($method === 'PUT') {
  65. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
  66. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  67. } elseif ($method === 'DELETE') {
  68. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
  69. }
  70. $response = curl_exec($ch);
  71. curl_close($ch);
  72. if ($response === false) {
  73. throw new Exception('Erreur lors de la requête API.');
  74. }
  75. return json_decode($response, true);
  76. }
  77. public static function refreshToken(string $expiredToken)
  78. {
  79. // Décoder le token sans vérifier son expiration
  80. $tokenParts = explode('.', $expiredToken);
  81. if (count($tokenParts) !== 3) {
  82. return null; // Token incorrect
  83. }
  84. $header = $tokenParts[0];
  85. $payload = $tokenParts[1];
  86. $signatureProvided = $tokenParts[2];
  87. // Vérifier la signature
  88. $signatureValid = hash_hmac('sha256', $header . '.' . $payload, self::$jwtSecret, true);
  89. $base64UrlSignature = self::base64UrlEncode($signatureValid);
  90. if ($base64UrlSignature !== $signatureProvided) {
  91. return null; // Signature incorrecte
  92. }
  93. // Décoder le payload
  94. $payloadDecoded = json_decode(self::base64UrlDecode($payload), true);
  95. // Vérifier si le token est expiré
  96. if (isset($payloadDecoded['exp']) && time() < $payloadDecoded['exp']) {
  97. return $expiredToken; // Le token n'est pas encore expiré, inutile de le rafraîchir
  98. }
  99. // Le token est expiré, régénérer un nouveau token avec les mêmes données mais une nouvelle expiration
  100. unset($payloadDecoded['exp']); // On enlève l'expiration actuelle
  101. $new = self::generateToken($payloadDecoded); // Générer un nouveau token
  102. user::updateJWTbyMd5(md5($expiredToken), $new);
  103. return $new;
  104. }
  105. /**
  106. * Déconnexion (facultatif) : Révoquer le token
  107. */
  108. public static function logout()
  109. {
  110. self::$jwtToken = null; // Supprimer le JWT
  111. }
  112. /**
  113. * Générer un JWT avec un payload
  114. */
  115. private static function generateToken($payload)
  116. {
  117. $header = json_encode([
  118. 'typ' => 'JWT',
  119. 'alg' => self::$jwtAlgorithm
  120. ]);
  121. $base64UrlHeader = self::base64UrlEncode($header);
  122. $base64UrlPayload = self::base64UrlEncode(json_encode($payload));
  123. // Créer la signature
  124. $signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, self::$jwtSecret, true);
  125. $base64UrlSignature = self::base64UrlEncode($signature);
  126. // Retourner le token complet
  127. return $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
  128. }
  129. /**
  130. * Valider un JWT
  131. */
  132. public static function validateToken(string $token)
  133. {
  134. $baseJWT = user::getInfosByJWT($token);
  135. if($baseJWT == FALSE){
  136. return false; // Token en base expirée
  137. }
  138. $tokenParts = explode('.', $token);
  139. if (count($tokenParts) !== 3) {
  140. return false; // Token incorrect
  141. }
  142. $header = $tokenParts[0];
  143. $payload = $tokenParts[1];
  144. $signatureProvided = $tokenParts[2];
  145. // Vérifier la signature
  146. $signatureValid = hash_hmac('sha256', $header . '.' . $payload, self::$jwtSecret, true);
  147. $base64UrlSignature = self::base64UrlEncode($signatureValid);
  148. if ($base64UrlSignature !== $signatureProvided) {
  149. return false; // Signature incorrecte
  150. }
  151. // Décoder le payload
  152. $payloadDecoded = json_decode(self::base64UrlDecode($payload), true);
  153. // Vérifier l'expiration du token
  154. if (isset($payloadDecoded['exp']) && time() >= $payloadDecoded['exp']) {
  155. return false; // Token expiré
  156. }
  157. return true; // Token valide
  158. }
  159. /**
  160. * Méthode utilitaire pour Base64 URL encoding
  161. */
  162. private static function base64UrlEncode($data)
  163. {
  164. return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
  165. }
  166. /**
  167. * Méthode utilitaire pour Base64 URL decoding
  168. */
  169. private static function base64UrlDecode($data)
  170. {
  171. return base64_decode(strtr($data, '-_', '+/'));
  172. }
  173. }