结论:$_server['http_authorization']为空非thinkphp问题,而是nginx/apache默认静默丢弃authorization头;nginx需配置proxy_set_header authorization $http_authorization;和underscores_in_headers on;,php-fpm还需fastcgi_param http_authorization $http_authorization;,apache则需requestheader或rewrite规则透传,且所有配置修改后必须重启服务。

直接说结论:$_SERVER['HTTP_AUTHORIZATION'] 为空,不是 ThinkPHP 的锅,是 Web 服务器(Nginx/Apache)在转发请求时把 Authorization 头静默丢弃了。不改服务器配置,PHP 层怎么读都是 null。
为什么 Nginx 下 $request->header('authorization') 总是空
Nginx 默认会过滤掉带下划线或大小写混用的 header,Authorization 正好命中规则(首字母大写 + 非标准字符集)。即使前端发了 Authorization: Bearer xxx,到 PHP 时 $_SERVER 里既没有 HTTP_AUTHORIZATION,也没有 REDIRECT_HTTP_AUTHORIZATION。
- 必须在
location块里加:proxy_set_header Authorization $http_authorization; - 同时开启:
underscores_in_headers on;(否则$http_authorization变量本身就不生效) - 如果用了
fastcgi_pass(常见于 PHP-FPM 场景),还要补上:fastcgi_param HTTP_AUTHORIZATION $http_authorization; - 验证方式:在中间件开头加
Log::info('server', $_SERVER);,搜索HTTP_AUTHORIZATION或REDIRECT_HTTP_AUTHORIZATION是否存在且非空
Apache 下 Authorization 头丢失的两种修复路径
Apache 的问题更隐蔽:CGI/FastCGI 模式下,Authorization 头根本不会进 PHP 环境,.htaccess 里的重写规则在某些配置下也无效。
- 推荐方案(配置文件级):在虚拟主机或主配置中启用
mod_headers,然后加这行:RequestHeader set Authorization "%{HTTP:Authorization}e" - 备选方案(.htaccess 可用但不稳定):
RewriteCond %{HTTP:Authorization} ^(.*)$+RewriteRule .* - [e=HTTP_AUTHORIZATION:%1],但仅对 mod_rewrite 生效,且不能用于 CGI 模式 - 关键点:不要依赖
SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0,它在 FastCGI 下基本失效 - 验证命令:
curl -H "Authorization: Bearer test" http://your-api.com/test,再看日志里$_SERVER输出
ThinkPHP 内部读取 Authorization 的正确姿势
即使服务器透传成功,TP6 的 $request->header() 方法仍有坑:它内部统一转小写,且对空格、前缀格式敏感。
- 必须用小写键名:
$request->header('authorization'),写'Authorization'或'bearer'都拿不到 - 别用
explode(' ', $auth)[1]提 token —— 前端可能多打一个空格,导致$auth是"Bearer xxx",explode后第一项是空字符串 - 安全提取写法:
$auth = $request->header('authorization'); $token = trim($auth) === 'Bearer' ? trim(substr($auth, 7)) : null; - 如果用了 JWT 中间件,确保没在中间件之前就调用过
$request->header()(某些早期 TP6 版本有缓存 bug,首次调用失败后后续都返回空)
CORS 和 Authorization 头冲突的典型表现
前端发的是带 Authorization 的跨域请求,但浏览器控制台报错 Request header field authorization is not allowed by Access-Control-Allow-Headers,说明后端响应头漏了 Authorization 字段。
-
Access-Control-Allow-Headers不能写['*']—— 只要credentials设为 true(比如要带 Cookie),就必须显式列出:['Content-Type', 'Authorization', 'X-Requested-With'] - 如果用了 TP6 的
Cors中间件,检查config/cors.php里的allowHeaders配置项,确认包含Authorization - 不要在 Nginx/Apache 层重复加
Access-Control-Allow-Headers,和 PHP 层冲突会导致响应头重复,浏览器直接拒绝 - OPTIONS 预检请求必须能被正确路由到(比如用
Route::options()或中间件拦截返回 204),否则连 header 都没机会发出去
最常被忽略的一点:所有修复都得重启 Web 服务(systemctl restart nginx 或 apachectl graceful),改完配置不重启等于没改。另外,开发环境用内置 PHP Server(php think run)时,Authorization 头默认可用,上线后切到 Nginx/Apache 就崩,这个落差很多人没意识到。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











