'JWT', 'alg' => 'HS256']); $payload = json_encode($payload); $base64UrlHeader = self::base64UrlEncode($header); $base64UrlPayload = self::base64UrlEncode($payload); $signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $secret, true); $base64UrlSignature = self::base64UrlEncode($signature); return $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature; } /** * Decode and verify a JWT token */ public static function decode($jwt, $secret) { $parts = explode('.', $jwt); if (count($parts) !== 3) { return false; } list($base64UrlHeader, $base64UrlPayload, $base64UrlSignature) = $parts; $signature = self::base64UrlDecode($base64UrlSignature); $expectedSignature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $secret, true); if (!hash_equals($signature, $expectedSignature)) { return false; } $payload = json_decode(self::base64UrlDecode($base64UrlPayload), true); // Check expiration if (isset($payload['exp']) && $payload['exp'] < time()) { return false; } return $payload; } /** * Create authentication token */ public static function createToken($email) { $payload = [ 'sub' => $email, 'iat' => time(), 'exp' => time() + JWT_EXPIRY ]; return self::encode($payload, JWT_SECRET_KEY); } /** * Verify token from Authorization header */ public static function verifyToken() { $headers = getallheaders(); if (!isset($headers['Authorization'])) { return false; } $authHeader = $headers['Authorization']; if (!preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) { return false; } $token = $matches[1]; $payload = self::decode($token, JWT_SECRET_KEY); return $payload; } /** * Base64 URL encode */ private static function base64UrlEncode($data) { return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($data)); } /** * Base64 URL decode */ private static function base64UrlDecode($data) { return base64_decode(str_replace(['-', '_'], ['+', '/'], $data)); } } /** * Require authentication middleware */ function requireAuth() { $payload = JWT::verifyToken(); if (!$payload) { http_response_code(401); echo json_encode(['error' => 'Unauthorized']); exit; } return $payload; }