PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]); } /** * Liest den Authorization-Header — auf vielen Apache/PHP-FPM-Setups landet er NICHT in * $_SERVER['HTTP_AUTHORIZATION'] (Header wird von PHP-FPM standardmäßig verworfen), sondern nur * in $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] (nach der .htaccess-Weiterleitung, siehe dort) oder * ist nur über getallheaders() erreichbar. Alle drei Quellen abklappern, statt sich auf eine zu * verlassen — genau das war die Ursache für "Login klappt, danach sofort Session abgelaufen". */ function ai_backend_authorization_header(): string { if (!empty($_SERVER['HTTP_AUTHORIZATION'])) { return $_SERVER['HTTP_AUTHORIZATION']; } if (!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) { return $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; } if (function_exists('getallheaders')) { foreach (getallheaders() as $name => $value) { if (strcasecmp($name, 'Authorization') === 0) { return $value; } } } return ''; } /** * Bearer-Token aus dem Authorization-Header lesen, gegen tokens.token_hash prüfen * (SHA-256, der Klartext wird nie gespeichert) und den zugehörigen aktiven User zurückgeben. * Sendet bei fehlendem/ungültigem/abgelaufenem Token selbst eine 401-Antwort und beendet das Skript. */ function ai_backend_authenticate(PDO $pdo): array { $header = ai_backend_authorization_header(); if (!preg_match('/^Bearer\s+(.+)$/i', $header, $m)) { ai_backend_fail(401, 'Kein gültiges Token übermittelt.'); } $tokenHash = hash('sha256', $m[1]); $stmt = $pdo->prepare( 'SELECT u.* FROM users u JOIN tokens t ON t.user_id = u.id WHERE t.token_hash = ? AND t.expires_at > NOW() AND u.is_active = 1 LIMIT 1' ); $stmt->execute([$tokenHash]); $user = $stmt->fetch(); if (!$user) { ai_backend_fail(401, 'Ungültiges oder abgelaufenes Token.'); } return $user; } /** Einheitliche Fehlerantwort als JSON, beendet danach das Skript. */ function ai_backend_fail(int $httpStatus, string $message): never { http_response_code($httpStatus); header('Content-Type: application/json'); echo json_encode(['error' => $message]); exit; }