Authorization header missing in PHP POST request
PhpApacheHttpHeaderAuthorizationPhp Problem Overview
I'm currently trying to read the authorization header in a PHP script that I'm calling with a POST request. The Authorization header is populated with a token. It seems the Authorization header is somehow removed before it arrives at my PHP script. I'm executing the post request with Postman (Chrome addon) and I enabled CORS in my PHP script. I don't have access to the apache server directly.
HTTP Request:
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 script:
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'];
The above script outputs '' (= nothing).
Php Solutions
Solution 1 - Php
After quite some time a found a solution to this problem. 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]
Solution 2 - Php
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]
Solution 3 - Php
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
Solution 4 - Php
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']
Solution 5 - Php
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 RewriteRule
s are workarounds and don't solve the root problem.
I tested this solution in 2021 with php7.4.
Solution 6 - Php
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.
Solution 7 - Php
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)
Solution 8 - Php
In my case if found it in $_SERVER["REDIRECT_HTTP_AUTHORIZATION"]
Solution 9 - Php
I don't know why my php 5.4.45 running on NGINX was refusing any custom header containing underscores:
ACCEPTED: CURLOPT_HTTPHEADER => array('Authorization: 123456')
REFUSED: CURLOPT_HTTPHEADER => array('my_Authorization: 123456')
I hope it can help someone. Cheers
Solution 10 - Php
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.
Solution 11 - Php
For me, enabling PHP-FPM on PHP 8.1 fixed the issue, without any amendment in htaccess.