Fehlermeldung
Wrong number of segments
Auch ausgegeben als
- UnexpectedValueException: Wrong number of segments
- Unexpected control character found
Bei der Ausgabe steht der Klassenname davor: „UnexpectedValueException: Wrong number of segments“. Mit dem Präfix `Bearer` entsteht stattdessen „Unexpected control character found“ (eine `DomainException`).
firebase/php-jwt (PHP) — UnexpectedValueException from JWT::decode
Was der Fehler bedeutet
`JWT::decode` hat die Eingabe an den Punkten aufgeteilt und nicht genau drei Teile erhalten; es handelt sich also nicht um ein kompaktes JWS, und sonst wurde nichts geprüft. In PHP-Anwendungen ist die häufigste Ursache ein leerer String: Der Webserver hat den Header `Authorization` nicht an PHP weitergegeben, und der Code ist auf `''` zurückgefallen. Ein Token, das noch das Präfix `Bearer ` trägt, hat drei Segmente, scheitert aber einen Schritt später, typischerweise mit „Unexpected control character found“ vom JSON-Decoder.
Warum der Fehler auftritt
Der Header Authorization hat PHP nie erreicht
häufigApache mit PHP-FPM oder CGI entfernt `Authorization`, sofern er nicht so konfiguriert ist, dass er den Header weitergibt, und manche Hosting-Panels tun dasselbe. Der Client sendet den Header, aber `$_SERVER['HTTP_AUTHORIZATION']` ist nicht gesetzt.
Der Wert ist kein JWT
häufigEine Session-ID, ein opakes OAuth-Access-Token, ein API-Schlüssel oder `"null"`, gesendet von einem JavaScript-Client, der noch kein Token hatte.
Schema oder Anführungszeichen stecken noch im String
gelegentlichÜbergibst du den ganzen Wert des Headers oder ein JSON-kodiertes Token samt Anführungszeichen, scheitert das Parsen des ersten Segments.
So behebst du den Fehler
- 1.
Header robust auslesen und Form prüfen
Suche den Header an allen Stellen, an denen ihn unterschiedliche Server-Setups ablegen, akzeptiere nur `Bearer <three base64url segments>` und antworte sonst mit 401.
php function bearerToken(): ?string { $header = $_SERVER['HTTP_AUTHORIZATION'] ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] // Apache + mod_rewrite ?? (function_exists('apache_request_headers') ? (apache_request_headers()['Authorization'] ?? '') : ''); if (!preg_match('/^Bearer\s+([A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*)$/', $header, $m)) { return null; } return $m[1]; } - 2.
Apache den Header weitergeben lassen
`CGIPassAuth On` (Apache 2.4.13+) oder eine Rewrite-Regel macht `Authorization` für PHP sichtbar.
text # Apache with PHP-FPM / CGI: pass the Authorization header through CGIPassAuth On # or, with mod_rewrite: RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]