提问人:jimmy 提问时间:10/21/2014 最后编辑:igorsantos07jimmy 更新时间:10/27/2023 访问量:108680
PHP POST 请求中缺少授权标头
Authorization header missing in PHP POST request
问:
我目前正在尝试读取我使用 POST 请求调用的 PHP 脚本中的授权标头。Authorization 标头填充了令牌。似乎 Authorization 标头在到达我的 PHP 脚本之前以某种方式被删除了。我正在使用 Postman(Chrome 插件)执行 post 请求,并在我的 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'];
上面的脚本输出 '' (= nothing)。
答:
不知何故,标题被剥离了。通过在我的 中添加以下行,我能够让它工作。Authorization
.htaccess
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
评论
Authorization
CGIPassAuth
.htaccess
下面的数组包含请求标头,$_SERVER变量中可能缺少这些标头
$headers = apache_request_headers();
(对于“HTTP_X_REQUESTED_WITH”ajax 标头尤其如此,它可以通过以下方式找到:$headers['X_REQUESTED_WITH']
评论
我必须首先将其添加到我的机器Apache配置文件中:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
在 Linux 上/etc/apache2/apache2.conf
在 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]
2022 年更新:
根据多条评论,您可以通过多种方式获得相同的结果(尽管由于几年前在我所有项目中都切换到 nginx,因此无法确认):
您可以按项目放置,也可以“全局”放置在 中,也可以将每个项目放在块中的文件中。
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
.htaccess
httpd.conf
httpd-vhosts.conf
<VirtualHost>
评论
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
AllowOverride ALL
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
这个解决方案(如上所述)在欺骗 httpd.conf 文件后对我有用:
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
为了实现这一点,httpd.conf 必须在我的 Alias 部分包含这些指令:
AllowOverride All
Options FollowSymLinks
第一个太开放了(是的,我知道),但是如果您将 AllowOverride None 完全避免使用 .htaccess。
此外,如果您不使用 FollowSymLinks 等(基于 Apache 文档),也可以避免 RewriteRule()
评论
就我而言,如果在 $_SERVER[“REDIRECT_HTTP_AUTHORIZATION”] 中找到它
我想用一个具体的案例来扩展前面的答案。
我在 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 的解决方案:
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>
现在,数组中有一个键。"HTTP_AUTHORIZATION"
$_SERVER
编辑:似乎还有另一个具有相同值的键。"REDIRECT_HTTP_AUTHORIZATION"
如果您使用 WHM + CPanel + PHP,并且您的显示结果像这样,则缺少授权
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
)
现在只需完成这些步骤即可。
第 1 步:.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服务器(如果没有重新启动服务器,则无法正常工作)
步骤4:我的结果显示
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
)
这项工作已经完成。在执行这些步骤并再次显示相同的错误后,请在此处发表评论
评论
此问题最优雅的解决方案是在 中启用此指令。.htaccess
CGIPassAuth On
此指令是 apache 核心的一部分,不需要启用任何特殊模块。请参阅此处的文档。
将 php-fpm 与 apache 一起使用时会出现问题(与在 apache 中直接使用 php 模块相反)。
这是一种安全措施,可防止敏感数据通过 fcgi 从 apache 传输到 php。
此解决方案不仅修复了 ,而且还修复了 ,如上所述,用于“基本”身份验证
在 PHP 的官方文档中。$_SERVER["HTTP_AUTHORIZATION"]
$_SERVER["PHP_AUTH_USER"]
在我看来,所有其他涉及通过 s 或使用 s 设置环境变量的解决方案都是解决方法,并不能解决根本问题。HTTP_AUTHORIZATION
SetEnvIf
RewriteRule
我在 2021 年用 php7.4 测试了这个解决方案。
评论
我们能够通过切换到使用 php-fpm (FastCGI) 而不是使用 apache 的 mod_php 来解决同样的问题。标头未受干扰地传递给 FastCGI,但似乎被mod_php剥离了。
对我来说,在 PHP 8.1 上启用 PHP-FPM 解决了这个问题,没有对 htaccess 进行任何修改。
评论
我使用了我在其他地方找到的略有不同的语法(不记得它在哪里),这也适用于项目的 .htacess 文件。
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
对我来说,我通过在我的 vhost apache 文件中添加以下行解决了这个问题:
# Uncomment the following line to force Apache to pass the Authorization
# header to PHP: required for "basic_auth" under PHP-FPM and FastCGI
#
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
在 Apache 配置文件中添加“CGIPassAuth On”有点风险,因为它会将所有内容传递给 FCGI。
当我通过 Apache 在 PHP/Symfony 中调用 Web 服务时,我遇到了 Authorization 标头消失的问题,这个问题出现在 php-8.2-apache Docker 镜像中。
您必须在 docker-compose.yml 中挂载 Apache conf 文件,如下所示:
#in docker-compose file (the last line) :
volumes:
- './app:/var/www/html'
- './app/logs/apache2:/var/log/apache2'
- './docker/conf/apache2/vhost.conf:/etc/apache2/sites-enabled/000-default.conf'
#apache vhost 文件:
<VirtualHost *:80>
DocumentRoot /var/www/html/public
# Uncomment the following line to force Apache to pass the Authorization
# header to PHP: required for "basic_auth" under PHP-FPM and FastCGI
#
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
<Directory /var/www/html/public>
AllowOverride Indexes Limit Options
Options FollowSymlinks
Require all granted
FallbackResource /index.php
</Directory>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Authorization}i\"\n" custom_combined
CustomLog /var/log/apache2/access.log custom_combined
</VirtualHost>
梅杜克斯
评论
确保您使用的PHP版本支持PHP-FPM,您可以在屏幕截图显示的最后一列中看到,从CPANEL中获取,如果它不起作用,请尝试切换PHP版本,当您尝试测试时,我的PHP 8.2工作
下一个:拒绝访问 js 和 css
评论