Mensaje de error
Wrong number of segments
También se muestra como
- UnexpectedValueException: Wrong number of segments
- Unexpected control character found
Al imprimirse, va precedido del nombre de la clase: «UnexpectedValueException: Wrong number of segments». En el caso del prefijo `Bearer`, en cambio, se produce «Unexpected control character found» (una `DomainException`).
firebase/php-jwt (PHP) — UnexpectedValueException from JWT::decode
Qué significa
`JWT::decode` dividió la entrada por los puntos y no obtuvo exactamente tres partes, así que no es un JWS compacto y no se comprobó nada más. En las aplicaciones PHP, el origen más habitual es una cadena vacía: el servidor web no pasó el encabezado `Authorization` a PHP y el código recurrió a `''`. Un token que aún lleva el prefijo `Bearer ` tiene tres segmentos, pero falla un paso después, normalmente con «Unexpected control character found» del decodificador JSON.
Por qué ocurre
El encabezado Authorization nunca llegó a PHP
frecuenteApache con PHP-FPM o CGI elimina `Authorization` salvo que se configure para pasarlo, y algunos paneles de hosting hacen lo mismo. El cliente envía el encabezado, pero `$_SERVER['HTTP_AUTHORIZATION']` no está definido.
El valor no es un JWT
frecuenteUn ID de sesión, un token de acceso OAuth opaco, una clave de API o `"null"` enviado por un cliente JavaScript que aún no tenía token.
Esquema o comillas que quedan en la cadena
ocasionalPasar el valor completo del encabezado, o un token codificado en JSON con comillas, hace fallar el análisis del primer segmento.
Cómo solucionarlo
- 1.
Leer el encabezado de forma robusta y validar el formato
Busca en los lugares donde las distintas configuraciones de servidor colocan el encabezado, acepta solo `Bearer <three base64url segments>` y, en caso contrario, responde 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.
Hacer que Apache pase el encabezado
`CGIPassAuth On` (Apache 2.4.13+) o una regla de reescritura hacen visible `Authorization` para PHP.
text # Apache with PHP-FPM / CGI: pass the Authorization header through CGIPassAuth On # or, with mod_rewrite: RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]