Message d’erreur
Wrong number of segments
Également affiché sous la forme
- UnexpectedValueException: Wrong number of segments
- Unexpected control character found
À l’affichage, le message est précédé du nom de la classe : « UnexpectedValueException: Wrong number of segments ». Le cas du préfixe `Bearer` produit à la place « Unexpected control character found » (une `DomainException`).
firebase/php-jwt (PHP) — UnexpectedValueException from JWT::decode
Ce que cela signifie
`JWT::decode` a découpé l’entrée selon les points sans obtenir exactement trois parties : ce n’est donc pas un JWS compact, et rien d’autre n’a été vérifié. Dans les applications PHP, la cause la plus fréquente est une chaîne vide : le serveur web n’a pas transmis l’en-tête `Authorization` à PHP, et le code s’est rabattu sur `''`. Un jeton qui porte encore le préfixe `Bearer ` a bien trois segments, mais échoue une étape plus loin, généralement avec « Unexpected control character found », émis par le décodeur JSON.
Pourquoi cela se produit
L’en-tête Authorization n’est jamais parvenu à PHP
fréquenteApache avec PHP-FPM ou CGI supprime `Authorization` s’il n’est pas configuré pour le transmettre, et certains panneaux d’hébergement font de même. Le client envoie bien l’en-tête ; `$_SERVER['HTTP_AUTHORIZATION']` n’est pas défini.
La valeur n’est pas un JWT
fréquenteUn identifiant de session, un jeton d’accès OAuth opaque, une clé d’API, ou `"null"` envoyé par un client JavaScript qui n’avait pas encore de jeton.
Schéma ou guillemets restés dans la chaîne
occasionnellePasser la valeur complète de l’en-tête, ou un jeton encodé en JSON avec ses guillemets, fait échouer l’analyse du premier segment.
Comment corriger l’erreur
- 1.
Lire l’en-tête de façon robuste et valider sa forme
Cherchez l’en-tête aux différents endroits où le placent les diverses configurations de serveur, n’acceptez que `Bearer <three base64url segments>` et répondez 401 dans les autres cas.
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.
Faire transmettre l’en-tête par Apache
`CGIPassAuth On` (Apache 2.4.13+) ou une règle de réécriture rend `Authorization` visible pour PHP.
text # Apache with PHP-FPM / CGI: pass the Authorization header through CGIPassAuth On # or, with mod_rewrite: RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]