PHP POST 请求中缺少授权标头

Authorization header missing in PHP POST request

提问人:jimmy 提问时间:10/21/2014 最后编辑:igorsantos07jimmy 更新时间:10/27/2023 访问量:108680

问:

我目前正在尝试读取我使用 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)。

php Apache HTTP 授权

评论

0赞 jimmy 10/22/2014
有人知道我还可以检查什么来调试问题吗?
0赞 9swampy 5/9/2022
检查 php 变量 $_SERVER 数组,以防您的网站被重定向 -> REDIRECT_AUTHORIZATION

答:

270赞 jimmy 11/7/2014 #1

不知何故,标题被剥离了。通过在我的 中添加以下行,我能够让它工作。Authorization.htaccess

RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

评论

2赞 Deemoe 12/17/2014
在 Php 5.4 和 Apache 上尝试将 HTTP 基本授权与我的 REST API 一起使用时,我遇到了同样的问题。我已经修改了 .htaccess 文件以支持 rest api 的 RewriteEngine On,同样,当我在 PHP 中查询它们时,除了授权之外,我的所有请求标头似乎都在那里。您的修复是正确的,谢谢!
17赞 spice 12/29/2018
4 年后,在 PHP 7.2 上,这仍然很重要!很棒的修复!
18赞 Jerry 3/23/2019
我本来打算投赞成票的......然后我意识到我已经有,上次我遇到这个问题。
5赞 James John McGuire 'Jahmic' 5/2/2020
优秀的解决方案...现在有人可以解释一下发生了什么吗?这仅发生在某些服务器上。为什么它会被剥离?
11赞 patricknelson 8/12/2020
我也对此感到好奇;显然,出于安全原因,Apache默认不会传递标头。相反,您必须使用指令手动启用它(大约 2.4.13),该指令在目录配置中或目录配置中有效。此功能也适用于以前的版本,但我找不到为这些旧版本解释此功能的文档。AuthorizationCGIPassAuth.htaccess
8赞 Grigoreas P. 9/8/2017 #2

下面的数组包含请求标头,$_SERVER变量中可能缺少这些标头

$headers = apache_request_headers();

(对于“HTTP_X_REQUESTED_WITH”ajax 标头尤其如此,它可以通过以下方式找到:$headers['X_REQUESTED_WITH']

评论

0赞 Alexis Wilke 11/4/2018
虽然这是正确的,但我可以看到正确的标头(这比使用 .htaccess 解决方案要好得多!)数组中的键区分大小写。因此,如果不先调整数组,您将无法轻松访问它们......
1赞 Alexis Wilke 11/4/2018
请参阅有关将数组的键转换为小写或大写的答案:stackoverflow.com/questions/4240001/...
0赞 Alex Abreu Mulet 8/2/2023
请注意!apache_request_headers() 是一个函数,只有在使用 Apache 作为 Web 服务器时才定义。因此,所有拥有 nginx 等的人都被排除在外。
80赞 FullStack Alex 2/17/2019 #3

我必须首先将其添加到我的机器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.htaccesshttpd.confhttpd-vhosts.conf<VirtualHost>

评论

12赞 Mohit 9/14/2019
您可以添加 .htaccess。这对我有用。SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
2赞 mazend 2/8/2020
它对我有用。我正在使用 aws lightsail 所以......我在 /opt/bitnami/apache2/conf/httpd.conf 中添加了代码。此外,我认为重新启动服务器是必要的。sudo /opt/bitnami/ctlscript,.sh 重新启动 Apache。
0赞 Ade 3/16/2020
@Mohit 对我来说,这必须在Apache配置文件(或virtualhost配置)中 - 即当添加到.htaccess文件时它不起作用。我不知道为什么这是因为我设置了AllowOverride ALL
0赞 David Copano Jiménez 5/10/2020
我在使用 Laravel Passport 时遇到错误,服务器返回了未经身份验证。有了这个回复,我能够修复它。救命者!
1赞 ViBoNaCci 11/1/2022
为了清楚起见:您可以按项目放入 .htaccess,也可以在 httpd.conf 中“全局”放置,或者将每个项目放在 <VirtualHost> 块中的 httpd-vhosts.conf 文件中。SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
1赞 hgc2002 12/10/2019 #4

这个解决方案(如上所述)在欺骗 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()

评论

0赞 Quentin Merlin 6/14/2021
如何在iIS中做到这一点?
2赞 Pavel Popov 8/28/2020 #5

就我而言,如果在 $_SERVER[“REDIRECT_HTTP_AUTHORIZATION”] 中找到它

3赞 akinuri 1/21/2021 #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 的解决方案

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"

17赞 Purvesh Tejani 1/30/2021 #7

如果您使用 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
)

这项工作已经完成。在执行这些步骤并再次显示相同的错误后,请在此处发表评论

评论

0赞 Purvesh Tejani 5/15/2021
随时@Sachem
0赞 Quentin Merlin 6/14/2021
如何在 iIS web.config 中执行此操作
0赞 3m1n3nc3 11/23/2023
这是唯一对我有用的东西,我已经把它收藏了。感谢分享。
25赞 santiago arizti 9/2/2021 #8

此问题最优雅的解决方案是在 中启用此指令。.htaccess

CGIPassAuth On

此指令是 apache 核心的一部分,不需要启用任何特殊模块。请参阅此处的文档。

将 php-fpm 与 apache 一起使用时会出现问题(与在 apache 中直接使用 php 模块相反)。

这是一种安全措施,可防止敏感数据通过 fcgi 从 apache 传输到 php。

此解决方案不仅修复了 ,而且还修复了 ,如上所述,用于“基本”身份验证 在 PHP 的官方文档中。$_SERVER["HTTP_AUTHORIZATION"]$_SERVER["PHP_AUTH_USER"]

在我看来,所有其他涉及通过 s 或使用 s 设置环境变量的解决方案都是解决方法,并不能解决根本问题。HTTP_AUTHORIZATIONSetEnvIfRewriteRule

我在 2021 年用 php7.4 测试了这个解决方案。

评论

0赞 waseemrakab 9/14/2021
这适用于带有 fastcgi 处理程序的 PHP 8.0.10 !!
0赞 zoran 10/29/2021
效果很好!我收到“400 错误请求:请求中未设置 JSON Web 令牌”,这修复了它。
0赞 Ahmad Gulzar 11/1/2023
使用 PHP 8.2 启用了 PHP-FPM,但我无法收到授权标头,这解决了问题。
0赞 nullability 11/18/2021 #9

我们能够通过切换到使用 php-fpm (FastCGI) 而不是使用 apache 的 mod_php 来解决同样的问题。标头未受干扰地传递给 FastCGI,但似乎被mod_php剥离了。

1赞 Mahmoud 3/30/2022 #10

对我来说,在 PHP 8.1 上启用 PHP-FPM 解决了这个问题,没有对 htaccess 进行任何修改。

评论

0赞 MAChitgarha 8/24/2022
可能只有从CGI到PHP-FPM的转换才重要。PHP版本应该是无关紧要的。
1赞 ulrich 8/11/2023 #11

我使用了我在其他地方找到的略有不同的语法(不记得它在哪里),这也适用于项目的 .htacess 文件。

RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
1赞 Mehdi 9/21/2023 #12

对我来说,我通过在我的 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>

梅杜克斯

评论

0赞 hh skladby 11/24/2023
“CGIPassAuth On ...将所有内容传递给 FCGI“听起来很可怕。它只会过滤掉一些身份验证标头(如果“打开”),并且只有在您允许任意人在您的网络空间中创建 CGI 脚本时才有风险。
0赞 MUHINDO 10/27/2023 #13

确保您使用的PHP版本支持PHP-FPM,您可以在屏幕截图显示的最后一列中看到,从CPANEL中获取,如果它不起作用,请尝试切换PHP版本,当您尝试测试时,我的PHP 8.2工作在此处输入图像描述