PHP POST 请求中缺少授权头

我当前正在尝试读取 PHP 脚本中的授权头部,我正在使用 POST 请求调用该脚本。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'];

上面的脚本输出”(= nothing)。

95593 次浏览

Somehow, the Authorization header was stripped away. By adding the following lines in my .htaccess, I was able to get it to work.

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

Below array holds request headers, that may be missing in $_SERVER variable

$headers = apache_request_headers();

(Especially true for 'HTTP_X_REQUESTED_WITH' ajax header, which will be found this way as: $headers['X_REQUESTED_WITH']

I had first to add this to my machines Apache config file:

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

On Linux in /etc/apache2/apache2.conf

On Mac using Homebrew in /usr/local/etc/httpd/httpd.conf

On Mac with "native" Apache: /private/etc/apache2/httpd.conf or: /etc/apache2/httpd.conf

Adding this to .htaccess didn't work for any reason:

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

Update 2022:

According to multiple comments you can achieve the same result in multiple ways (can't confirm it though due to switching to nginx in all my projects a couple of years ago):

you can place SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 in .htaccess per project basis, but also 'globally' in httpd.conf, or per project in the httpd-vhosts.conf file within <VirtualHost> block.

This solution (mentioned above) worked for me after tricking httpd.conf file:

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

To make this work, httpd.conf had to include these directives in my Alias section:

AllowOverride All
Options FollowSymLinks

The first one is too open (yes, I know), but .htaccess is totally avoided if you put AllowOverride None.

Also, RewriteRule is avoided too is you don't use FollowSymLinks or so (based in Apache docs)

In my case if found it in $_SERVER["REDIRECT_HTTP_AUTHORIZATION"]

I want to extend the previous answers with a specific case.

I'm using LAMP (bitnami) on AWS (Lightsail). My code is written using CodeIgniter 3. So I already have a .htacess file and this is what's in it:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>

I wanted to implement jimmy's solution:

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

But how? Everyone seems to "suggest" something, but not be specific about it. Having multiple rewrite conditions/rules seemed problematic. I'm not an Apache guru, so I had to experiment. I managed to get it working in the following way:

<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>

Now, there's an "HTTP_AUTHORIZATION" key in the $_SERVER array.

Edit: There seems to be also another key "REDIRECT_HTTP_AUTHORIZATION" with the same value.

if you use WHM + CPanel + PHP and if your show result like this here missing 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
)

Now just flow these steps.

Step 1: .htaccess file add

RewriteEngine On


RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Step 2: add in your PHP file like index.php

1. getallheaders();


2. apache_request_headers();
 

3. $SERVER['REDIRECT_HTTP_AUTHENTICATION'];

You can use anyone.

Step 3: go to WHM Panel and flow this navigation

Home » Service Configuration » Apache Configuration » Include Editor » Pre VirtualHost Include » All Version

Add this line

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

and Restart Apache Server (if not restart the server then not working properly)

Step 4: My Result Show

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
)

this work has done. after you flow these steps and again show the same error please comment here

The most elegant solution to this problem is enabling this directive in .htaccess.

CGIPassAuth On

This directive is part of the apache core and doesn't require any special module to be enabled. See the documentation here.

The problem happens when using php-fpm with apache (as oposed to using the php module directly in apache).

This is a security measure that prevents sensitive data to be transfered from apache to php through fcgi.

This solution fixes not only $_SERVER["HTTP_AUTHORIZATION"] but also $_SERVER["PHP_AUTH_USER"], used in "Basic" authentication as described in php's official documentation.

In my opinion, all other solutions that involve setting the HTTP_AUTHORIZATION environment variable through SetEnvIf or with RewriteRules are workarounds and don't solve the root problem.

I tested this solution in 2021 with php7.4.

We were able to address this same issue by switching to use the php-fpm (FastCGI) instead of using mod_php for apache. The header is passed unmolested to FastCGI but seems to be stripped by mod_php.

For me, enabling PHP-FPM on PHP 8.1 fixed the issue, without any amendment in htaccess.