应执行 composer require firebase/php-jwt:^6.10,因其是唯一推荐、长期活跃、无框架绑定的通用jwt库;v6+要求php≥7.4,需正确引入命名空间、使用jwt::alg_hs256常量、确保密钥非空,并配置web服务器透传authorization头。

直接执行 composer require firebase/php-jwt:^6.10,别搜“jwt”或装其他名字相似的包——90% 的安装失败都源于包名写错或版本不兼容。
为什么 composer require jwt 会报错
Composer 不认识 jwt 这个包名,它不是官方注册包。市面上叫 “jwt” 的包有十几个,但绝大多数已停止维护、不支持 PHP 7.4+,或者只是某个框架的私有封装(比如 tymon/jwt-auth 是 Laravel 专用,php-jwt 根本不存在)。
- 唯一推荐、长期活跃、无框架绑定的通用库是
firebase/php-jwt - 搜
composer require jwt或composer require php-jwt必然失败 - 如果项目还在用 PHP 7.2,得降级:用
composer require firebase/php-jwt:^5.2,v6+ 要求 ≥7.4
JWT::encode() 报 Class not found 怎么办
装完不代表能用——firebase/php-jwt 没有全局函数,全靠命名空间和自动加载,漏掉 use 就直接炸。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 文件顶部必须写:
use Firebase\JWT\JWT;(v6.10+ 还要配合use Firebase\JWT\Key;) -
JWT::encode()第三个参数不能传字符串"HS256",得传JWT::ALG_HS256(v6.10+ 强制要求) - 密钥(
$key)必须是非空字符串,不能是null、''或数组,否则抛InvalidArgumentException - 示例正确写法:
use Firebase\JWT\JWT; use Firebase\JWT\Key; <p>$payload = ['user_id' => 123, 'exp' => time() + 3600]; $key = $_ENV['JWT_SECRET'] ?? 'dev-key'; $token = JWT::encode($payload, $key, 'HS256'); // v6.10 兼容字符串写法,但推荐用 JWT::ALG_HS256</p>
Web 服务器没透传 Authorization 头怎么办
本地测试能过,一上 Nginx/Apache 就 HTTP_AUTHORIZATION 为空,十有八九是服务器过滤了带点号的 header,或者大小写不敏感导致取不到。
- Nginx 需加配置:
fastcgi_pass_request_headers on;和proxy_set_header Authorization $http_authorization; - Apache 要开启
mod_rewrite并在.htaccess加:RewriteCond %{HTTP:Authorization} ^(.*)+RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] - PHP 中取头别写
$_SERVER['http_authorization'](小写),统一用$_SERVER['HTTP_AUTHORIZATION']或更稳的getallheaders()['Authorization'] ?? '' - 验证是否生效:在入口加
var_dump($_SERVER['HTTP_AUTHORIZATION'] ?? 'MISSING');
鉴权时 SignatureInvalidException 到底哪错了
这个异常几乎全是密钥或请求头格式问题,不是代码逻辑问题。错误信息模糊,容易往解码逻辑里钻牛角尖。
- 检查请求头:必须是
Authorization: Bearer eyJhbGciOi...,Bearer首字母大写、后面跟一个空格、再跟 token 字符串 - 服务端密钥必须和签发时**字节级一致**:从
.env读的话,确认没多出换行符(trim($_ENV['JWT_SECRET'])更安全) - 别把 token 拆成三段后再传给
JWT::decode()——它只接受原始完整字符串,不是 base64url 解码后的 payload - 如果用了反向代理或 CDN,确认它们没主动 strip 掉
Authorization头
真正难的不是装包,而是密钥管理、头透传、时间偏移(JWT::$leeway = 60 得设)、以及防重放(jti + Redis)。这些细节不处理,token 看似能生成,一上线就崩。










