Authorization header missing in PHP POST request

87,712

Solution 1

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

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

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

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.

Solution 5

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

Share:
87,712

Related videos on Youtube

jimmy
Author by

jimmy

Updated on March 31, 2022

Comments

  • jimmy
    jimmy about 2 years

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

    • jimmy
      jimmy over 9 years
      Anyone got an idea what else I could check to debug the issue?
    • 9swampy
      9swampy almost 2 years
      Check the php variable $_SERVER array in case your sites been redirected -> REDIRECT_AUTHORIZATION
  • Deemoe
    Deemoe over 9 years
    I had the same problem when trying to use HTTP Basic Authorization with my REST api on Php 5.4 and Apache. I had modified the .htaccess file to support RewriteEngine On for the rest api and similarly all my request headers seemed to be there except authorization when I query them in PHP. Your fix is correct, thanks!
  • user1260501
    user1260501 about 7 years
    This fixes the same problem occurring when using CodeIgniter 3 using the codeigniter-restserver library when custom routes are being used. Interestingly enough it also creates two headers, HTTP_AUTHORIZATION and REDIRECT_HTTP_AUTHORIZATION, both with an identical value.
  • Calin
    Calin almost 7 years
    Awesome answer, works perfectly. If you have other conditions in your .htaccess file, I've placed this at the top (first).
  • Alexis Wilke
    Alexis Wilke over 5 years
    Although this is correct, I can see the correct header in there (and this is much better than using the .htaccess solution!) the key in the array are CASE SENSITIVE. So you can't easily access them without tweaking the array first...
  • Alexis Wilke
    Alexis Wilke over 5 years
    See this answer about transforming the keys of an array to lower or upper case: stackoverflow.com/questions/4240001/…
  • spice
    spice over 5 years
    4 years later on PHP 7.2 and this is still relevant! Awesome fix!
  • Joey
    Joey about 5 years
    glad I found it at the first hit in google, saved me headache... works perfectly
  • Jerry
    Jerry about 5 years
    I was going to upvote this... then I realized I already had, the last time I had this problem.
  • viniciussvl
    viniciussvl almost 5 years
    Thank you, your response help me
  • Mohit
    Mohit over 4 years
    You can add SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 in .htaccess. That worked for me.
  • mazend
    mazend about 4 years
    It worked for me. I'm using aws lightsail so.. I added the code in /opt/bitnami/apache2/conf/httpd.conf. In addition I think restarting server is necessary. sudo /opt/bitnami/ctlscript.sh restart apache.
  • Ade
    Ade about 4 years
    @Mohit For me this had to be in the Apache config file (or virtualhost config) – i.e. it did not work when added to the .htaccess file. I don't know why this is because I have AllowOverride ALL set
  • Jahmic
    Jahmic about 4 years
    Excellent solution... Now can someone explain what is going on? This only happens on some servers. Why does it get stripped out?
  • David Copano Jiménez
    David Copano Jiménez almost 4 years
    I was having errors with Laravel Passport, the server returned Unauthenticated. With this response I was able to fix it. Lifesaver!
  • patricknelson
    patricknelson over 3 years
    I was curious about this too; apparently Apache does not pass the Authorization header by default for security reasons. Instead, you must manually enable it (circa 2.4.13) with the CGIPassAuth directive, valid in .htaccess or in directory configs. This functionality has applied to previous versions as well, but I'm not able to find documentation explaining this for those older versions.
  • Hevski
    Hevski about 3 years
    This solved the issue on a Bitnami wordpress server too. The Apache2 config is put in the file opt/bitnami/apache2/conf/httpd.conf I added SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 and it got rid of the error. Thank you
  • Pradip Shenolkar
    Pradip Shenolkar about 3 years
    This is still relevant in the year 2021 for the version PHP 7.4.
  • prafferty
    prafferty about 3 years
    Thank you! Updating .htaccess alone did not do the trick, but adding that to my httpd.conf file did the trick after a restart.
  • Purvesh Tejani
    Purvesh Tejani almost 3 years
    anytime @Sachem
  • Quentin Merlin
    Quentin Merlin almost 3 years
    in IIS , how i can make that ? could you please help me ?
  • Quentin Merlin
    Quentin Merlin almost 3 years
    How to do that in iIS ?
  • Quentin Merlin
    Quentin Merlin almost 3 years
    How to do that in iIS web.config
  • Quentin Merlin
    Quentin Merlin almost 3 years
    How to do that in iIS ?
  • waseemrakab
    waseemrakab over 2 years
    this works in php 8.0.10 with fastcgi handler !!
  • zoran
    zoran over 2 years
    Works great! I was getting "400 Bad Request: JSON Web Token not set in request" and this fixed it.
  • soulshined
    soulshined over 2 years
    For brevity, this works within <VirtualHost> elements in the httpd-vhosts.conf file as well. FYI, local apache server on windows
  • Nelson Katale
    Nelson Katale almost 2 years
    Thank you sooooo much. This answer definitely saved my day.
  • Ncoder
    Ncoder almost 2 years
    Found this interesting note -- This is a "security feature", to prevent the user's credentials from being passed to all CGI scripts (which might not be trusted, if you don't control the server). PHP normally sets the $_SERVER['HTTP_AUTHORIZATION'] superglobal (and associated array elements) from the HTTP Authorization header, but if it's been stripped by Apache then it can't. The RewriteRule directive in .htaccess attempts to "fix" this by setting an HTTP_AUTHORIZATION