diff --git a/includes/UniFiController.php b/includes/UniFiController.php index 58ed54f..90dce55 100644 --- a/includes/UniFiController.php +++ b/includes/UniFiController.php @@ -6,6 +6,7 @@ class UniFiController { private $siteId; private $cookieFile; private $csrfToken = null; + private $sessionCookie = null; public function __construct($controllerUrl, $username, $password, $siteId) { $this->controllerUrl = rtrim($controllerUrl, '/'); @@ -46,10 +47,18 @@ class UniFiController { CURLOPT_HEADERFUNCTION => function($ch, $header) { $parts = explode(':', $header, 2); if (count($parts) === 2) { - $name = trim($parts[0]); + $name = strtolower(trim($parts[0])); $value = trim($parts[1]); - if (strtolower($name) === 'x-csrf-token') { + if ($name === 'x-csrf-token') { $this->csrfToken = $value; + } elseif ($name === 'set-cookie') { + // Extract TOKEN value directly — cookie jar may not persist + // cookies with the 'Partitioned' attribute on some libcurl versions + $cookieParts = explode(';', $value); + $first = trim($cookieParts[0]); + if (strpos($first, 'TOKEN=') === 0) { + $this->sessionCookie = $first; + } } } return strlen($header); @@ -100,12 +109,19 @@ class UniFiController { CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, - CURLOPT_COOKIEFILE => $this->cookieFile, CURLOPT_TIMEOUT => 10, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_HTTPHEADER => $headers ]; + // Prefer manually extracted cookie over file-based jar — the Partitioned + // attribute on the TOKEN cookie prevents some libcurl versions from writing it + if ($this->sessionCookie !== null) { + $options[CURLOPT_COOKIE] = $this->sessionCookie; + } else { + $options[CURLOPT_COOKIEFILE] = $this->cookieFile; + } + if ($method === 'GET') { $options[CURLOPT_HTTPGET] = true; } elseif ($method === 'POST') { diff --git a/test.php b/test.php index 6beca36..485c158 100644 --- a/test.php +++ b/test.php @@ -190,29 +190,52 @@ try { if (file_exists($cookieFile)) { $cookieContents = file_get_contents($cookieFile); echo "Cookie-Datei:
";
- echo htmlspecialchars($cookieContents ?: '(leer)');
+ echo htmlspecialchars($cookieContents ?: '(leer — TOKEN hat Partitioned-Attribut, libcurl schreibt es nicht in die Jar-Datei)');
echo "";
}
+ // Extract TOKEN from Set-Cookie header (the fix for Partitioned cookie issue)
+ $tokenCookie = null;
+ foreach ($responseHeaders as $h) {
+ if (stripos($h, 'set-cookie:') === 0) {
+ $cookieVal = trim(substr($h, strlen('set-cookie:')));
+ $cookieParts = explode(';', $cookieVal);
+ $first = trim($cookieParts[0]);
+ if (strpos($first, 'TOKEN=') === 0) {
+ $tokenCookie = $first;
+ }
+ }
+ }
+ if ($tokenCookie) {
+ echo "✓ TOKEN aus Set-Cookie-Header extrahiert: " . htmlspecialchars(substr($tokenCookie, 0, 40)) . "…