跳到主要内容
ecdsa.com
firebase/php-jwt (PHP)PHP

错误信息

Wrong number of segments

也可能输出为

  • UnexpectedValueException: Wrong number of segments
  • Unexpected control character found

打印时会带上类名前缀:“UnexpectedValueException: Wrong number of segments”。带有 `Bearer` 前缀的情况则会产生“Unexpected control character found”(一个 `DomainException`)。

firebase/php-jwt (PHP) — UnexpectedValueException from JWT::decode

含义

`JWT::decode` 按点号拆分输入后,得到的不是恰好三个部分,因此输入不是紧凑格式的 JWS,其他内容都没有检查。在 PHP 应用中,最常见的来源是空字符串:Web 服务器没有把 `Authorization` 请求头传给 PHP,代码于是回退为 `''`。仍带有 `Bearer ` 前缀的令牌虽然有三段,但会在下一步失败,通常是 JSON 解码器报出“Unexpected control character found”。

原因

修复方法

  1. 1.

    稳妥地读取请求头并校验格式

    在不同服务器配置存放该请求头的各个位置查找,只接受 `Bearer <three base64url segments>`,否则返回 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. 2.

    让 Apache 传递该请求头

    `CGIPassAuth On`(Apache 2.4.13+)或一条重写规则可以把 `Authorization` 暴露给 PHP。

    text
    # Apache with PHP-FPM / CGI: pass the Authorization header through
    CGIPassAuth On
    # or, with mod_rewrite:
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

相关错误

浏览完整的签名错误库