最常见的原因是包名拼错,正确命令是composer require firebase/php-jwt;若PHP版本不兼容可加@latest;国内网络问题可切换阿里云镜像;Class not found需检查autoload引入及重新install;v6+需四参数encode且注意密钥类型匹配;时间校验失败多因时区、时间戳类型或leeway设置不当。

composer require jwt库时提示找不到包
最常见原因是拼错了包名,官方维护的 PHP JWT 库是 firebase/php-jwt,不是 jwt/php-jwt 或 php-jwt。Composer 默认只搜 Packagist 官方源,拼错就直接报 Could not find package xxx。
- 执行
composer require firebase/php-jwt(注意斜杠是正斜杠,不是反斜杠) - 如果项目已锁死 PHP 版本(比如
"php": "^7.4"),而你用的是 PHP 8.2,某些旧版firebase/php-jwt(如 v5.x)会装不上——此时加@latest强制拉最新兼容版:composer require firebase/php-jwt:@latest - 国内网络偶尔会卡在下载 zip 包,可临时切镜像:
composer config -g repo.packagist composer https://packagist.phpcomposer.com(但该镜像已停更,推荐改用阿里云:composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/)
安装后 use 语句报 Class not found
装完没报错,但代码里写 use Firebase\JWT\JWT; 运行却提示 Class 'Firebase\JWT\JWT' not found,基本是 autoloader 没生效或路径没刷新。
- 确认
vendor/autoload.php已被引入(通常在入口文件第一行:require __DIR__ . '/vendor/autoload.php';) - 删掉
vendor和composer.lock,重新composer install(不是require)——尤其当你从 Git 拉项目但没带vendor时,这步不能跳 -
firebase/php-jwtv6+ 要求 PHP >= 7.4,且类名大小写敏感;写成use firebase\jwt\jwt;(全小写)在 Linux 环境下必报错
JWT::encode() 报 ArgumentCountError
v6.0+ 版本彻底移除了三参数签名,老教程里的 JWT::encode($payload, $key, 'HS256') 会崩,错误信息是 Too few arguments to function Firebase\JWT\JWT::encode()。
- 新写法必须传四个参数:
JWT::encode($payload, $key, 'HS256', $keyId),其中$keyId可为null或字符串(如'my-key-1') - 更推荐用静态方法
JWT::sign()+JWT::encode()分离密钥和签名逻辑,避免混淆 - 密钥类型要匹配:
HS256用字符串密钥,RS256必须用OpenSSLAsymmetricKey对象(即openssl_pkey_get_private()返回值),混用直接抛异常
token 解析后 payload 时间字段校验失败
调 JWT::decode() 后报 ExpiredException 或 BeforeValidException,但明明时间看起来没问题——问题常出在时区或时间戳精度上。
-
iat、nbf、exp字段必须是整数时间戳(秒级),传time()是对的,但传new DateTime()->format('U')或字符串数字(如"1712345678")可能触发类型弱比较失败 - 服务器时间和客户端时间差超过
$leeway(默认 0 秒),就会校验失败;可在 decode 前设全局容错:JWT::$leeway = 60;(放宽 60 秒) - 别手动改
exp字段再 encode——JWT 签名会失效,decode 时直接抛SignatureInvalidException
实际用的时候,最麻烦的不是装不上,而是装上了、引入了、也 encode 成功了,结果 decode 时静默失败(比如返回空数组),这种往往卡在 leeway、时区、或者 key 类型不匹配上,得挨个打日志看。











