| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- <?php
- /**
- * Classe jwt
- *
- * Cette classe gère la génération, la validation et la manipulation des JSON Web Tokens (JWT).
- */
- class jwt
- {
- /**
- * @var string|null $jwtToken Le jeton JWT actuellement utilisé.
- */
- private static $jwtToken;
- /**
- * @var string $jwtSecret Clé secrète utilisée pour signer les tokens.
- */
- private static $jwtSecret = JWT_PRIVATE_KEY;
- /**
- * @var string $jwtAlgorithm Algorithme utilisé pour signer les JWT (par défaut : HS256).
- */
- private static $jwtAlgorithm = "HS256";
- /**
- * Initialise les configurations pour l'authentification.
- *
- * @param string $loginUrl URL de connexion.
- * @param string $apiBaseUrl URL de base de l'API.
- * @param string $email Adresse e-mail de l'utilisateur.
- * @param string $password Mot de passe de l'utilisateur.
- */
- public static function init($loginUrl, $apiBaseUrl, $email, $password)
- {
- // Le JWT sera stocké dans cette propriété statique
- self::$jwtToken = null;
- }
- /**
- * Vérifie si une session JWT est valide.
- *
- * @return string JSON indiquant si l'utilisateur est authentifié.
- */
- public static function checkSession()
- {
- // Vérifie si le JWT existe et n'est pas expiré
- if (self::$jwtToken && self::validateToken(self::$jwtToken)) {
- return json_encode(['authenticated' => true, 'token' => self::$jwtToken]);
- } else {
- return json_encode(['authenticated' => false]);
- }
- }
- /**
- * Authentifie l'utilisateur et génère un JWT.
- *
- * @param array $_input Données d'entrée pour l'authentification.
- * @return array|false Données utilisateur avec le token ou FALSE en cas d'échec.
- */
- public static function authenticate(array $_input)
- {
- $user = user::authenticator($_input);
- if ($user["status"] == "success") {
-
- // Générer le JWT
- $user["token"] = self::generateToken($user);
- self::$jwtToken = $user["token"];
- return $user;
- } else {
- return FALSE;
- }
- }
- /**
- * Effectue une requête API authentifiée avec le JWT.
- *
- * @param string $endpoint Point de terminaison de l'API.
- * @param string $method Méthode HTTP (GET, POST, PUT, DELETE).
- * @param array $data Données à envoyer dans la requête.
- * @return array Réponse de l'API.
- * @throws Exception Si le JWT est invalide ou expiré.
- */
- public static function makeAuthenticatedRequest($endpoint, $method = 'GET', $data = [])
- {
- if (!self::$jwtToken) {
- throw new Exception('Aucun jeton JWT disponible. Veuillez vous authentifier.');
- }
- // Vérification du token avant d'effectuer une requête
- if (!self::validateToken(self::$jwtToken)) {
- throw new Exception('Jeton JWT invalide ou expiré. Veuillez vous authentifier à nouveau.');
- }
- $ch = curl_init();
- $url = DOMAIN_API . $endpoint;
- curl_setopt($ch, CURLOPT_URL, $url . "/");
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- // Ajouter le JWT dans l'en-tête d'autorisation
- curl_setopt($ch, CURLOPT_HTTPHEADER, [
- 'Authorization: Bearer ' . self::$jwtToken,
- 'Content-Type: application/json'
- ]);
- // Configuration des méthodes GET/POST/PUT/DELETE
- if ($method === 'POST') {
- curl_setopt($ch, CURLOPT_POST, true);
- curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
- } elseif ($method === 'PUT') {
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
- curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
- } elseif ($method === 'DELETE') {
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
- }
- $response = curl_exec($ch);
- curl_close($ch);
- if ($response === false) {
- throw new Exception('Erreur lors de la requête API.');
- }
- return json_decode($response, true);
- }
- /**
- * Rafraîchit un JWT expiré.
- *
- * @param string $expiredToken Le token expiré.
- * @return string|null Nouveau token ou null si échec.
- */
- public static function refreshToken(string $expiredToken)
- {
- // Décoder le token sans vérifier son expiration
- $tokenParts = explode('.', $expiredToken);
- if (count($tokenParts) !== 3) {
- return null; // Token incorrect
- }
- $header = $tokenParts[0];
- $payload = $tokenParts[1];
- $signatureProvided = $tokenParts[2];
- // Vérifier la signature
- $signatureValid = hash_hmac('sha256', $header . '.' . $payload, self::$jwtSecret, true);
- $base64UrlSignature = self::base64UrlEncode($signatureValid);
- if ($base64UrlSignature !== $signatureProvided) {
- return null; // Signature incorrecte
- }
- // Décoder le payload
- $payloadDecoded = json_decode(self::base64UrlDecode($payload), true);
- // Vérifier si le token est expiré
- if (isset($payloadDecoded['exp']) && time() < $payloadDecoded['exp']) {
- return $expiredToken; // Le token n'est pas encore expiré, inutile de le rafraîchir
- }
- // Le token est expiré, régénérer un nouveau token avec les mêmes données mais une nouvelle expiration
- unset($payloadDecoded['exp']); // On enlève l'expiration actuelle
- $new = self::generateToken($payloadDecoded); // Générer un nouveau token
- user::updateJWTbyMd5(md5($expiredToken), $new);
- return $new;
- }
- /**
- * Révoque le JWT actuel (déconnexion).
- */
- public static function logout()
- {
- self::$jwtToken = null; // Supprimer le JWT
- }
- /**
- * Génère un JWT avec un payload donné.
- *
- * @param array $payload Données à inclure dans le token.
- * @return string Le JWT généré.
- */
- private static function generateToken($payload)
- {
- $header = json_encode([
- 'typ' => 'JWT',
- 'alg' => self::$jwtAlgorithm
- ]);
- $base64UrlHeader = self::base64UrlEncode($header);
- $base64UrlPayload = self::base64UrlEncode(json_encode($payload));
- // Créer la signature
- $signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, self::$jwtSecret, true);
- $base64UrlSignature = self::base64UrlEncode($signature);
- // Retourner le token complet
- return $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
- }
- /**
- * Valide un JWT donné.
- *
- * @param string $token Le token à valider.
- * @return bool TRUE si le token est valide, FALSE sinon.
- */
- public static function validateToken(string $token)
- {
- $baseJWT = user::getInfosByJWT($token);
- if($baseJWT == FALSE){
- return false; // Token en base expirée
- }
- $tokenParts = explode('.', $token);
- if (count($tokenParts) !== 3) {
- return false; // Token incorrect
- }
- $header = $tokenParts[0];
- $payload = $tokenParts[1];
- $signatureProvided = $tokenParts[2];
- // Vérifier la signature
- $signatureValid = hash_hmac('sha256', $header . '.' . $payload, self::$jwtSecret, true);
- $base64UrlSignature = self::base64UrlEncode($signatureValid);
- if ($base64UrlSignature !== $signatureProvided) {
- return false; // Signature incorrecte
- }
- // Décoder le payload
- $payloadDecoded = json_decode(self::base64UrlDecode($payload), true);
- // Vérifier l'expiration du token
- if (isset($payloadDecoded['exp']) && time() >= $payloadDecoded['exp']) {
- return false; // Token expiré
- }
- return true; // Token valide
- }
- /**
- * Encode des données en Base64 URL.
- *
- * @param string $data Les données à encoder.
- * @return string Les données encodées.
- */
- private static function base64UrlEncode($data)
- {
- return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
- }
- /**
- * Décode des données en Base64 URL.
- *
- * @param string $data Les données à décoder.
- * @return string Les données décodées.
- */
- private static function base64UrlDecode($data)
- {
- return base64_decode(strtr($data, '-_', '+/'));
- }
- }
|