bin2hex(random_bytes(32)), 'created_at' => time(), ]; } return $_SESSION['csrf_tokens'][$formName]['token']; } /** * Valide le token soumis */ public static function validateToken(string $submittedToken, string $formName = 'default'): bool { $session = $_SESSION['csrf_tokens'][$formName] ?? null; if (!$session) return false; // Expiration après 1 heure if (time() - $session['created_at'] > 3600) { self::destroyToken($formName); return false; } $valid = hash_equals($session['token'], $submittedToken); // Token à usage unique : on le supprime après validation if ($valid) { self::destroyToken($formName); } return $valid; } /** * Supprime un token */ public static function destroyToken(string $formName = 'default'): void { unset($_SESSION['csrf_tokens'][$formName]); } /** * Retourne le champ HTML caché à insérer dans les formulaires */ public static function field(string $formName = 'default'): string { $token = self::generateToken($formName); return '' . ''; } }