PHP POST 请求中缺少授权标头
Posted
技术标签:
【中文标题】PHP POST 请求中缺少授权标头【英文标题】:Authorization header missing in PHP POST request 【发布时间】:2014-12-16 00:57:01 【问题描述】:我目前正在尝试读取我通过 POST 请求调用的 php 脚本中的授权标头。 Authorization 标头填充了一个令牌。似乎 Authorization 标头在到达我的 PHP 脚本之前以某种方式被删除。我正在使用 Postman(Chrome 插件)执行发布请求,并在我的 PHP 脚本中启用了 CORS。我无法直接访问 apache 服务器。
HTTP 请求:
Accept:*/*
Accept-Encoding:gzip,deflate
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,ja;q=0.2
Authorization:Bearer mytoken
Cache-Control:no-cache
Connection:keep-alive
Content-Length:32
Content-Type:text/plain;charset=UTF-8
Host:www.myhost.com
Origin:chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko)
Chrome/38.0.2125.104 Safari/537.36
PHP 脚本:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With, Content-Type, Accept");
header("Content-Type: application/json");
$headers = getallheaders();
echo $headers['Authorization'];
以上脚本输出 ''(= 无)。
【问题讨论】:
有人知道我还能检查什么来调试问题吗? 【参考方案1】:经过一段时间后,找到了解决此问题的方法。不知何故,Authorization
标头被剥离了。通过在我的.htaccess
中添加以下行,我能够让它工作。
RewriteEngine On
RewriteCond %HTTP:Authorization ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
【讨论】:
我在 PHP 5.4 和 Apache 上尝试将 HTTP 基本授权与我的 REST api 一起使用时遇到了同样的问题。我已经修改了 .htaccess 文件以支持 RewriteEngine On 其余 api 并且类似地,当我在 PHP 中查询它们时,除了授权之外,我的所有请求标头似乎都在那里。您的修复是正确的,谢谢! 4 年后在 PHP 7.2 上,这仍然是相关的!很棒的修复! 我本来打算对此投赞成票的...然后我意识到我已经投过票了,上次我遇到了这个问题。 优秀的解决方案...现在有人可以解释发生了什么吗?这只发生在某些服务器上。为什么会被剥离? 我也很好奇这个;显然,出于安全原因,Apache 默认不传递Authorization
标头。相反,您必须使用 CGIPassAuth
指令手动启用它(大约 2.4.13),该指令在 .htaccess
或目录配置中有效。此功能也适用于以前的版本,但我无法找到解释这些旧版本的文档。【参考方案2】:
我必须首先将它添加到我的机器 Apache 配置文件中:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
在/etc/apache2/apache2.conf
中的 Linux 上
在 Mac 上使用 Homebrew 在 /usr/local/etc/httpd/httpd.conf
在带有“本机”Apache 的 Mac 上:/private/etc/apache2/httpd.conf
或:/etc/apache2/httpd.conf
将此添加到 .htaccess 中没有任何原因:
RewriteEngine On
RewriteCond %HTTP:Authorization ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
【讨论】:
谢谢你的回复对我有帮助 您可以在.htaccess 中添加SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
。这对我有用。
它对我有用。我正在使用 aws lightail 所以.. 我在 /opt/bitnami/apache2/conf/httpd.conf 中添加了代码。另外我认为重启服务器是必要的。 sudo /opt/bitnami/ctlscript.sh 重启 apache。
@Mohit 对我来说,这必须在 Apache 配置文件(或虚拟主机配置)中——也就是说,当添加到 .htaccess 文件时,它确实不起作用。我不知道这是为什么,因为我设置了AllowOverride ALL
我在使用 Laravel Passport 时遇到错误,服务器返回未经身份验证。有了这个响应,我能够修复它。救命稻草!【参考方案3】:
如果你使用 WHM + CPanel + PHP 并且你的显示结果像这样在这里缺少 Authorization
Array
(
[Host] => domain.com
[Connection] => keep-alive
[Cache-Control] => max-age=0
[Upgrade-Insecure-Requests] => 1
[User-Agent] => Mozilla/5.0
[Accept] => text/html,application/xhtml+xml
[Sec-Fetch-Site] => none
[Sec-Fetch-Mode] => navigate
[Sec-Fetch-User] => ?1
[Sec-Fetch-Dest] => document
[Accept-Encoding] => gzip, deflate, br
[Accept-Language] => en
)
现在只需执行这些步骤。
第一步: .htaccess 文件添加
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%HTTP:Authorization]
第 2 步: 添加您的 PHP 文件,例如 index.php
1. getallheaders();
2. apache_request_headers();
3. $SERVER['REDIRECT_HTTP_AUTHENTICATION'];
你可以使用任何人。
第 3 步:转到 WHM 面板并进行此导航
Home » Service Configuration » Apache Configuration » Include Editor » Pre VirtualHost Include » All Version
添加这一行
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
并重新启动 Apache 服务器(如果不重新启动服务器则无法正常工作)
第四步:我的结果展示
Array
(
[Authorization] => hhRbRZtypswriasabjn3xHT+9Fe9sWHjejhID/YTmookDdrN7WyTUULWwCvmMRiW0RaDRtozLVnvjnl
[User-Agent] => PostmanRuntime/7.26.8
[Accept] => */*
[Cache-Control] => no-cache
[Host] => domain.com
[Accept-Encoding] => gzip, deflate, br
[Connection] => keep-alive
[Content-Type] => application/x-www-form-urlencoded
[Content-Length] => 3
[X-Https] => 1
)
这项工作已经完成。在您完成这些步骤并再次显示相同的错误后,请在此处发表评论
【讨论】:
随时@Sachem 如何在 iis web.config 中做到这一点【参考方案4】:下面的数组包含请求标头,$_SERVER 变量中可能缺少这些标头
$headers = apache_request_headers();
(对于“HTTP_X_REQUESTED_WITH”ajax 标头尤其如此,可以通过以下方式找到:
$headers['X_REQUESTED_WITH']
【讨论】:
虽然这是正确的,但我可以在其中看到正确的标题(这比使用 .htaccess 解决方案要好得多!)数组中的键区分大小写。因此,如果不先调整数组,您将无法轻松访问它们... 查看这个关于将数组的键转换为小写或大写的答案:***.com/questions/4240001/…【参考方案5】:解决这个问题最优雅的方法是在.htaccess
中启用这个指令。
CGIPassAuth On
此指令是 apache 核心的一部分,不需要启用任何特殊模块。请参阅文档here。
在 apache 中使用 php-fpm 时会出现问题(与直接在 apache 中使用 php 模块相反)。
这是一种安全措施,可防止敏感数据通过 fcgi 从 apache 传输到 php。
此解决方案不仅修复了$_SERVER["HTTP_AUTHORIZATION"]
,还修复了$_SERVER["PHP_AUTH_USER"]
,如所述的“基本”身份验证中使用
在php的official documentation.
在我看来,所有其他涉及通过SetEnvIf
或RewriteRule
s 设置HTTP_AUTHORIZATION
环境变量的解决方案都是变通方法,并不能解决根本问题。
我在 2021 年用 php7.4 测试了这个解决方案。
【讨论】:
这适用于带有 fastcgi 处理程序的 php 8.0.10 !! 效果很好!我收到“400 Bad Request: JSON Web Token not set in request”,这解决了它。【参考方案6】:我想用一个具体的案例来扩展之前的答案。
我在 AWS (Lightsail) 上使用 LAMP (bitnami)。我的代码是使用 CodeIgniter 3 编写的。所以我已经有一个 .htacess
文件,这就是其中的内容:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
我想实现jimmy's solution:
RewriteEngine On
RewriteCond %HTTP:Authorization ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
但是怎么做呢?每个人似乎都在“建议”某事,但并不具体。有多个重写条件/规则似乎有问题。我不是 Apache 大师,所以我不得不进行实验。我设法通过以下方式使其工作:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %HTTP:Authorization ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
现在,$_SERVER
数组中有一个 "HTTP_AUTHORIZATION"
键。
编辑:似乎还有另一个键 "REDIRECT_HTTP_AUTHORIZATION"
具有相同的值。
【讨论】:
【参考方案7】:这个解决方案(上面提到的)在欺骗 httpd.conf 文件后对我有用:
RewriteEngine On
RewriteCond %HTTP:Authorization ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
为了完成这项工作,httpd.conf 必须在我的别名部分中包含这些指令:
AllowOverride All
Options FollowSymLinks
第一个太开放了(是的,我知道),但是如果你放 AllowOverride None,.htaccess 是完全可以避免的。
此外,RewriteRule 也可以避免,因为您不使用 FollowSymLinks 左右(基于 Apache 文档)
【讨论】:
如何在 IIS 中做到这一点?【参考方案8】:我不知道为什么我在 nginx 上运行的 php 5.4.45 拒绝任何包含下划线的自定义标头:
接受: CURLOPT_HTTPHEADER => 数组('授权:123456')
拒绝: CURLOPT_HTTPHEADER => 数组('my_Authorization: 123456')
我希望它可以帮助某人。干杯
【讨论】:
【参考方案9】:就我而言,如果在 $_SERVER["REDIRECT_HTTP_AUTHORIZATION"] 中找到它
【讨论】:
【参考方案10】:我们能够通过切换到使用 php-fpm (FastCGI) 而不是使用 mod_php 来解决同样的问题。标头未受干扰地传递给 FastCGI,但似乎被 mod_php 剥离。
【讨论】:
以上是关于PHP POST 请求中缺少授权标头的主要内容,如果未能解决你的问题,请参考以下文章