3

I am attempting to create a simple API to connect a mobile app and website together.

For my API, I have developed a simple URL routing script to help keep URLs clean and simple for my website, and I was hoping to apply it to my API scripts too, however, it's been creating some issues getting the AUTHORIZATION header in the API.

I am using this as my .htaccess file for my API site:

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

My index.php controls where all the traffic is routed like this:

@list($page_url,$url_vars) = explode('?',$page_url);

$rules = array(                         
    '{v1/items$}' => 'items.php'
);
$found = false;

foreach ($rules as $pattern => $target) {
    if (preg_match($pattern, $page_url, $params)) {
        @list($page,$query) = explode('?',$target);
        $query = preg_replace_callback('/\$params\[(\d+)\]/',function($m) use ($params) { 
            return $params[$m[1]];
        }, $query);
        parse_str($query, $url_query_vars);
        extract($url_query_vars);
        print_r($url_query_vars);
        require $page;
        $found = true;
        break;
    }
}

So, once the URL /v1/items is hit, the router script about will require the items.php on the page.

Everything works as expected with routing the URLs and getting the API to render, the only problem I have ran into is when I want to include an AUTHORIZATION header in my call, the API does not receive that header, and I think it may because of my URL routing.

On my site if I use this CURL call, the AUTHORIZATION header is not recieved:

$token = "080042cad6356ad5dc0a720c18b53b8e53d4c274";

$ch = curl_init('https://api.local.dev/v1/items'); // Initialise cURL
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
   'Content-Type: application/json',
   'Authorization: Bearer ' . $token
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
echo $result;

But, if I remove the URL routing and just hit the index.php and remove the Rewrite Rules for everything to go through the index.php, then I can see the AUTHORIZATION headers.

Any ideas on what may be causing this issue?

zeropsi
  • 682
  • 9
  • 24
  • 1
    Try to debug the information in the `$_SERVER` array, with `var_dump($_SERVER);`. It could very well be that some headers are prepended with `REDIRECT_`. See [this question of mine](https://stackoverflow.com/questions/2267976/apache-setenv-prepends-redirect-what-gives) from years ago, or [search other questions about this issue](https://stackoverflow.com/search?q=%5Bapache%5D+REDIRECT_+is%3Aquestion). – Decent Dabbler May 20 '20 at 01:39
  • @zeropsi I tried your script all things is ok but the difference is with your simulation is `https` check your code without that – Mohsen May 20 '20 at 02:02
  • 1
    @DecentDabbler sent me down a rabbit hole with the `REDIRECT_` prepended header suggestion and I came across a few posts regarding PHP + fastcgi and then adding `SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0` to your `.htaccess`. Once I did that, the AUTHORIZATION headers were showing up. – zeropsi May 20 '20 at 02:05

1 Answers1

3

Pass the required header directly to PHP backend via the env:

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

Add this line to .httaccess or to <VirtualHost> of `httpd.conf. If adding to VirtualHost, don’t forget to restart Apache after that.

OmniPotens
  • 1,125
  • 13
  • 30
  • What's the difference between `SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1` and `SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0` in your `.htaccess` file? – zeropsi May 26 '20 at 21:04
  • I haven't tried the other solution. if you use `SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1`, you receive the token in `$_SERVER['HTTP_AUTHORIZATION']` or `$_SERVER['REDIRECT_HTTP_AUTHORIZATION']` – OmniPotens May 27 '20 at 07:36