This question already has answers here:
Apache 2.4 + PHP-FPM and Authorization headers
(4 answers)
Closed 11 months ago.
I have defined the rule into .htaccess like this:
# Ensure Authorization header is passed along
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
And I have passed "Authorization Bearer Token" into HTTP request like below:
:authority: demo.com
:method: POST
:path: /data-list
:scheme: https
accept: application/json, text/plain, */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,hi-IN;q=0.8,hi;q=0.7,gu-IN;q=0.6,gu;q=0.5
authorization: Bearer IiwiZGVzdCI6Imh0dHBzOlwvXC93Yy1rdW5hbGcubXlzaG9waWZ5LmNvbSIsImF1ZCI6ImI4NzMyYTZkNjcyMGFiNjNlN2IwZTRkNDExNzVhNTZlIiwic3ViIjoiNDQ1MDIxMjI2MjkiLCJleHAiOjE2NDg0NDEwODYsIm5iZiI6MTY0ODQ0MTAyNiwiaWF0IjoxNjQ4NDQxMDI2LCJqdGkiOiIyMjZiM2
content-length: 22
content-type: application/x-www-form-urlencoded
dnt: 1
origin: https://demo.com
referer: https://demo.com/data?hmac=18dc09298e1bd09d95c02ada793f57140804bf42380be07&host=d2Mta3VuYWxnLm15c2lmeS5jb20vYWRtaW4&locale=en-IN&session=55bfc54daf6945e3ca50b2da7f5830d88dcfcb8f4d103b97518166d9fd7b00c9&shop=demo.com×tamp=1648441021
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-origin
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36
But, using PHP variable $_SERVER or any other PHP variables I am not getting "authorization: Bearer Token".
I am using a digital ocean server for this.
I have tried PHP variables like $_SERVER or any other PHP variables that get "authorization: Bearer Token".
I am getting blank array response for printing $_SERVER['HTTP_AUTHORIZATION'].
Is there any information that I am missing?
Works fine for me with this code in .htaccess :
RewriteCond %{HTTP:Authorization} .+
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%0]
I tried to reproduce the issue but didn't get any error. Try to make the same request.
HTTP-Request
POST /data-list
Host: demo.com
authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9XXXXXXX
In PHP
function getToken(){
$bearerToken = null;
if (isset($_SERVER['AUTHORIZATION'])) {
$bearerToken = $_SERVER['AUTHORIZATION'];
}elseif (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
$bearerToken = $_SERVER["HTTP_AUTHORIZATION"];
}elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
$bearerToken = $_SERVER["REDIRECT_HTTP_AUTHORIZATION"];
}
return $bearerToken;
}
echo getToken(); // This returned a Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9XXXXXXX
Related
I hosted my website on a VPS with only one domain name.
I've an API build with API Platform and a front build with React.
I set up 2 vhosts one for my API and one for my front like that :
API :
<VirtualHost *:80>
ServerName my-api.project.fr
ServerAlias www.my-api.project.fr
DocumentRoot path/to/my/api-project/public
DirectoryIndex /index.php
<Directory path/to/my/api-project/public>
AllowOverride None
Order Allow,Deny
Allow from All
FallbackResource /index.php
</Directory>
</VirtualHost>
FRONT :
<VirtualHost *:80>
ServerName my-front.project.fr
ServerAlias www.my-front.project.fr
DocumentRoot path/to/my/front-project/build
DirectoryIndex index.html
<Directory "path/to/my/front-project/build">
Options +FollowSymLinks
AllowOverride all
Require all granted
FallbackResource /index.html
</Directory>
</VirtualHost>
Before each request I authenticate my front via an API call which returns a token which I put in the local storage. The url is: http://my-api.fr/api/guest/client/generate-public-token
I have no problem with this call, it works perfectly.
However, I've a registration endpoint (http://my-api.fr/api/guest/account/register) which doesn't work and the browser returns : Access to XMLHttpRequest at 'http://my-api.project.fr/api/guest/account/register' from origin 'http://my-front.project.fr' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. I really don't understand why this call doesn't work but not the other one...
In my API, I've Nelmio Bundle and my config is :
nelmio_cors:
defaults:
origin_regex: true
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization', 'Origin']
expose_headers: ['Link']
max_age: 3600
paths:
'^/': ~
Variable CORS_ALLOW_ORIGIN is equal to ^https?://my-front.project.fr(:[0-9]+)?$ but it still doesn't work.
I don't know if it can help someone but headers of my request are :
POST /api/guest/account/register HTTP/1.1
Host: my-api.project.fr
Connection: keep-alive
Content-Length: 120
Accept: application/json, text/plain, */*
Authorization: Bearer my_token
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
Content-Type: application/json;charset=UTF-8
Origin: http://my-front.project.fr
Referer: http://my-front.project.fr/register
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
Thanks in advance.
Bad config on my API Vhost...
I've to change AllowOverride None by AllowOverride All beacuse I've an .htaccess file
sounds like you need cors https://enable-cors.org/server_php.html. If you don't have access to configure Apache, you can still send the header from a PHP script. It's a case of adding the following to your PHP scripts:
<?php
header("Access-Control-Allow-Origin: *");
As new Opera 65 came few days ago with address bar redesign, I have noticed an issues on my web page.
While typing or copying an address into the bar, Opera sends requests to server, however, I am not able to capture the requests in PHP, as it seems, Fetch API is used under the hood.
Is there any way to deny or block the Fetch API requests in PHP 7 or Apache 2.4? In other words, block the requests on server side produced by Opera while typing / copying (PHP preferred)?
Particularly, I need to exclude GET requests providing an action with hash key in a query (test in the sample bellow).
When the address is copied (from mail for e.g.) to the address bar, Opera sends the request "in the background", the request is executed, however after submitting the address by Enter, second request returns error, because of forbidden operation (hash key is not valid anymore).
From Apache log:
127.0.0.1 - - [29/Nov/2019:01:56:08 +0100] "GET /? HTTP/1.1" 200 179736
127.0.0.1 - - [29/Nov/2019:01:56:08 +0100] "GET /?t HTTP/1.1" 200 179813
127.0.0.1 - - [29/Nov/2019:01:56:08 +0100] "GET /?te HTTP/1.1" 200 179808
127.0.0.1 - - [29/Nov/2019:01:56:08 +0100] "GET /?tes HTTP/1.1" 200 179819
127.0.0.1 - - [29/Nov/2019:01:56:08 +0100] "GET /?test HTTP/1.1" 200 179823
From Wireshark (one of the requests):
/?test HTTP/1.1
Host: sk.localhost
Connection: keep-alive
Sec-Fetch-Site: none
Sec-Fetch-Mode: no-cors
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36 OPR/65.0.3467.48
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Used technologies:
PHP 7.3.7, Apache/2.4.39
The requests can be denied (response sent) by Apache rewrite conditions or PHP response based on parsed headers.
Opera sends two Fetch API headers while typing:
Sec-Fetch-Site: none
Sec-Fetch-Mode: no-cors
List of all headers can be found at https://w3c.github.io/webappsec-fetch-metadata/.
To not sent a full response (not engage PHP) for requests with this headers, you can use Apache 2.4 mod rewrite module:
RewriteCond %{HTTP:Sec-Fetch-Site} ^none$ [NC]
RewriteCond %{HTTP:Sec-Fetch-Mode} ^no-cors$ [NC]
RewriteRule ^ - [R=204,L]
or send response via PHP (sample using Kohana/Koseven FW):
$header_sec_fetch_site = $this->request->headers('Sec-Fetch-Site');
$header_sec_fetch_mode = $this->request->headers('Sec-Fetch-Mode');
if (isset($header_sec_fetch_site, $header_sec_fetch_mode)
&& $header_sec_fetch_site == 'none'
&& $header_sec_fetch_mode == 'no-cors')
{
$message = 'Header ' . $header_sec_fetch_mode . ' received. No content for this request.';
Log::instance()->add(Log::NOTICE, $message);
throw HTTP_Exception::factory(204, $message, array(
':uri' => Request::current()->uri(),
));
}
The headers should be available in global variables:
$_SERVER['HTTP_SEC_FETCH_DEST']
$_SERVER['HTTP_SEC_FETCH_SITE']
$_SERVER['HTTP_SEC_FETCH_USER']
$_SERVER['HTTP_SEC_FETCH_MODE']
We have a proxy PHP script and access POST form data via
$postPayload = file_get_contents('php://input');
which usually works.
(The reason to not use $_POST is that we sometimes have duplicate form input names which PHP suppresses)
Now we have a form with
<form name="form" method="post"
action="/script.php" enctype="multipart/form-data">
In this case file_get_contents('php://input'); returns an empty string.
It can be reproduced with
curl 'http://localhost/script.php' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Referer: http://localhost/script.php?commandCode=NO_AUTH_REGIST_OPEN_USER&lang=de' -H 'Origin: http://misumi-europe.com.orange.imi.local' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36' -H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryk3IVneARm3kqJ0fs' --data-binary $'------WebKitFormBoundaryk3IVneARm3kqJ0fs\r\nContent-Disposition: form-data; name="commandCode"\r\n\r\nNO_AUTH_NEXT\r\n------WebKitFormBoundaryk3IVneARm3kqJ0fs\r\n' --compressed
How can I access the RAW POST data in this case?
I was able to fix it like this in .htaccess
<Files "script.php">
# make post data always available in the proxy
php_flag enable_post_data_reading 0
</Files>
multipart/form-data is not send to php://input, only to $_POST.
In php.ini you can set enable-post-data-reading=off to change this but $_POST will always be empty. See http://php.net/manual/en/ini.core.php#ini.enable-post-data-reading
You might set it for single pages using .htaccess
php_value enable-post-data-reading off
There is also an apache hack:
<Location "/backend/XXX.php">
SetEnvIf Content-Type ^(multipart/form-data)(.*) NEW_CONTENT_TYPE=multipart/form-data-alternate$2 OLD_CONTENT_TYPE=$1$2
RequestHeader set Content-Type %{NEW_CONTENT_TYPE}e env=NEW_CONTENT_TYPE
</Location>
See also: Get raw post data
Where is the debug information "Current character set: utf8" comming from?
It appears always first when I echoing something within my index.php (slim) script.
I really become desperate trying to suppress this.
May it caused by the .htaccess rules?
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]
Here my setting:
Server: Apache/2.4.9 (Win32) OpenSSL/1.0.1g PHP/5.5.11
X-Powered-By: PHP/5.5.11
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
The relevant section of the index.php:
function echoRespnse($status_code, $response) {
$app = \Slim\Slim::getInstance();
// Http response code
$app->status($status_code);
$app->config('debug', false);
// setting response content type to json
$app->contentType('application/json');
//$app->response()->header('Content-Type', 'application/json');
echo json_encode($response);
}
Any help would be greatly appreciated
I want to capture as much simple information on a web request with just PHP. What variables are available for me to store? Here's what I have so far:
https://gist.github.com/1363218
My wishlist for this function:
Turns language into an associative array ordered by weight
Add full name to language
Break server software into an associative array
Get the exact version of the platform, e.g., 'Windows 7 SP1' instead of just 'Windows'
Classify the request as being from a mobile device, a tablet, or a desktop
Am I missing anything else that could be useful?
Every information available to you are in variables, so an easy way to find the stuff you want is to have a look at $GLOBALS. Create a new PHP file and do print_r($GLOBALS);, and you'll see every information your script has gathered.
This includes everything from http headers (charset, encoding, language) to cookies, browser and operating system.
Take what you need: http://php.net/manual/en/reserved.variables.php
PHP_SELF /blog/article.php
GATEWAY_INTERFACE CGI/1.1
SERVER_ADDR Server IP: 217.112.82.20
SERVER_NAME www.URL.co.uk
SERVER_SOFTWARE Apache/2.2.15 (Win32) JRun/4.0 PHP/5.2.13
SERVER_PROTOCOL HTTP/1.0
REQUEST_METHOD GET / POST / PUT / HEAD
REQUEST_TIME Request start time: 1280149029
QUERY_STRING id=10&user=foo
DOCUMENT_ROOT /path/to/your/server/root/
HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9
HTTP_ACCEPT_CHARSET ISO-8859-1,utf-8;q=0.7,*;q=0.7
HTTP_ACCEPT_ENCODING gzip,deflate
HTTP_ACCEPT_LANGUAGE en-gb,en;q=0.5
HTTP_CONNECTION keep-alive
HTTP_HOST www.URL.co.uk
HTTP_REFFERER http://previous.url.com
HTTP_USER_AGENT Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729)
HTTPS 1
REMOTE_ADDR 193.60.128.69
REMOTE_HOST Client server's host name
REMOTE_PORT 5390
SCRIPT_FILENAME /path/to/this/script.php
SERVER_ADMIN webmaster#URL.co.uk
SERVER_PORT 80
SERVER_SIGNATURE Version signature: 5.123
SCRIPT_NAME /blog/article.php
REQUEST_URI /blog/article.php
$_SERVER['HTTP_USER_AGENT'].
This can you about user's operating system, as well as their browser.
For example
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en)