ThinkPHP中获取Authorization请求头需绕过SAPI限制:优先尝试$_SERVER['HTTP_AUTHORIZATION']及'REDIRECT_HTTP_AUTHORIZATION',再fallback到getallheaders(),最后考虑原始输入流;Apache需重写规则,Nginx需透传参数。

ThinkPHP 中如何获取 Authorization 请求头
ThinkPHP 默认会过滤掉带下划线和连字符的请求头,Authorization 正好属于被过滤的类型(因为 HTTP 头转为环境变量时,Authorization 变成 HTTP_AUTHORIZATION,但部分 CGI/SAPI 环境下它根本不会被写入 $_SERVER)。直接用 $request->header('authorization') 或 input('server.HTTP_AUTHORIZATION') 在不少部署环境下会返回空。
为什么 $request->header('authorization') 有时拿不到值
根本原因在于 SAPI 层限制:Apache 的 mod_php 模式下,Authorization 头默认被剥离;Nginx + PHP-FPM 则需要显式透传。即使透传了,ThinkPHP 的 Request::header() 内部依赖 $_SERVER,而 $_SERVER['HTTP_AUTHORIZATION'] 在 Apache 下通常不存在。
- Apache 用户必须在虚拟主机或
.htaccess中添加:RewriteCond %{HTTP:Authorization} .+RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] - Nginx 用户需在
location ~ \.php$块中加:fastcgi_param HTTP_AUTHORIZATION $http_authorization;
- 无论哪种服务器,都建议统一用原始输入流兜底,不依赖
$_SERVER
最稳妥的获取方式:从原始输入流解析
绕过所有 SAPI 和框架 header 解析逻辑,直接读取原始请求头。适用于 Bearer Token、Basic Auth 等常见格式,且兼容所有部署环境。
- 在控制器或中间件中使用:
$auth = request()->server('HTTP_AUTHORIZATION', '');<br>if (!$auth && function_exists('getallheaders')) {<br> $headers = getallheaders();<br> $auth = $headers['Authorization'] ?? $headers['authorization'] ?? '';<br>}<br>if (!$auth) {<br> // 最后尝试读取 PHP 输入流(适用于 CLI 或某些 FastCGI 场景)<br> $rawInput = file_get_contents('php://input');<br> // 注意:此时需配合前端明确发送 header,且该方式无法用于 GET 请求<br>} - 更轻量的写法(推荐放在基类或中间件):
$auth = $_SERVER['HTTP_AUTHORIZATION'] ?? ($_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ?? '');<br>if (!$auth && function_exists('getallheaders')) {<br> $headers = getallheaders();<br> $auth = $headers['Authorization'] ?? '';<br>}其中REDIRECT_HTTP_AUTHORIZATION是 Apache 的重写后变量名 - 拿到
$auth后按需解析:
– Bearer Token:preg_match('/Bearer\s+(.*)$/i', $auth, $matches)→ 取$matches[1]
– Basic:base64_decode(explode(' ', $auth)[1] ?? '')
TP6 中封装成公共方法的注意事项
如果项目中高频使用,建议封装到基础 Request 类或服务类中,但要注意两点:
立即学习“PHP免费学习笔记(深入)”;
- 不要只依赖
$this->header('authorization'),它在 Apache 下大概率失效 - 避免在
__construct()或初始化阶段就调用 header 方法——TP6 的Request实例可能尚未完成 header 解析,应改用request()->server()或getallheaders() - 若用中间件做鉴权,务必在
handle()中第一时间提取Authorization,并在后续逻辑中复用该值,避免多次调用getallheaders()(它在部分 SAPI 下有性能开销)
实际部署时,getallheaders() 不可用(如 CLI 模式或某些 FastCGI 配置),所以最健壮的方案永远是「先试 $_SERVER 变体,再 fallback 到 getallheaders(),最后考虑自定义 header 名透传」——别指望一个函数调用能横跨所有环境。



















