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.

在我看来,所有其他涉及通过SetEnvIfRewriteRules 设置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 请求中缺少授权标头的主要内容,如果未能解决你的问题,请参考以下文章

使用 JWT 缺少授权标头

使用 WCF 的 Http 请求中缺少授权标头

Ionic 3.5.2 http 请求中缺少授权标头

如果通过 Zuul API 网关发送请求,则缺少授权标头

POST 请求标头中的内容类型缺少 FormData 边界

为啥缺少授权标头?