【问题标题】:Authorization header missing in PHP POST requestPHP POST 请求中缺少授权标头
【发布时间】: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'];

以上脚本输出 ''(= 无)。

【问题讨论】:

  • 有人知道我还能检查什么来调试问题吗?

标签: php apache http header 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 解决方案要好得多!)数组中的键区分大小写。因此,如果不先调整数组,您将无法轻松访问它们...
  • 查看这个关于将数组的键转换为小写或大写的答案:stackoverflow.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 剥离。

        【讨论】:

          猜你喜欢
          • 2020-11-12
          • 2018-07-17
          • 2017-12-19
          • 1970-01-01
          • 2012-08-12
          • 1970-01-01
          • 2011-05-04
          • 2012-10-27
          相关资源
          最近更新 更多