Accessing a custom header in the API - php

I am sending a custom header to an API that I control using an AJAX call made via AngularJS.
Client (AngularJS)
var authorization_token = 'qwerty';
var custom_token_value = 'abc123';
$http.get('http://api.mywebsite.com/endpoint',{ headers:{'Auth':authorization_token,'Custom_Header':custom_token_value} }).then(function(res){
console.log(res.data);
});
Server (PHP 5.6)
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET,POST,PUT,DELETE');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Auth, Custom_Header");
$headers = getallheaders();
print_r($headers);
Response
Array
(
[Accept-Language] => en-US,en;q=0.9
[Accept-Encoding] => gzip, deflate
[Referer] => http://localhost:8080/
[Auth] => qwerty
[User-Agent] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36
[Origin] => http://localhost:8080
[Accept] => application/json, text/plain, */*
[Connection] => close
[Host] => api.mywebsite.com
)
Why am I not able to see Custom_Header?

For anyone having this issue, after some trial and error I've discovered that the reason Custom_Header was not showing up is because it contained an _ (underscore) character. Underscore characters apparently get dropped from header keys.
More info here: Why underscores are forbidden in HTTP header names

Related

Authorization not found In Php 8

Authorization not found when using below code in php 8 (xampp), it working in php 7(xampp)
Undefined Authorization key.
require "../vendor_big/autoload.php";
use \Firebase\JWT\JWT;
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
require $_SERVER['DOCUMENT_ROOT'].'/db.php';
$data = (json_decode(file_get_contents("php://input"), true));
$authHeader = apache_request_headers();
// print_r($authHeader);
$secret_key = "bmR0di1zYWxlcy1hcHAtYWR0ZWNoLXJpc2hp";
$jwt = null;
$arr = explode(" ", $authHeader["Authorization"]);
$jwt = $arr[1];
output
Array
(
[Host] => localhost:8080
[Connection] => keep-alive
[sec-ch-ua] => " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
[sec-ch-ua-mobile] => ?0
[sec-ch-ua-platform] => "Windows"
[Upgrade-Insecure-Requests] => 1
[User-Agent] => Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
[Accept] => text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
[Sec-Fetch-Site] => none
[Sec-Fetch-Mode] => navigate
[Sec-Fetch-User] => ?1
[Sec-Fetch-Dest] => document
[Accept-Encoding] => gzip, deflate, br
[Accept-Language] => en-US,en;q=0.9
)
how to get authorization?
Related table not found in database. When all table added then this issue not appear.

get value of http request headers in php

I am sending customer header in AJAX call,
$.ajaxSetup( {
data: {csrf_token : csrf},
headers: {"Csrf_token" : csrf}
});
Below is content which i seen in Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Cache-Control:no-cache
Connection:keep-alive
Content-Length:325
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:ci_session=kd817592v16s0p5b2f502hg39rs7olnu; csrf_cookie=22a1c908f3f036c90c2d0bf0f9b19497
Csrf_token:22a1c908f3f036c90c2d0bf0f9b19497
Host:testurl.com
Origin:http://testurl.com
Pragma:no-cache
Referer:http://testurl.com/xxx
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
X-Requested-With:XMLHttpRequest
But when i print this in PHP it only return below, i could not see my custom header "Csrf_token"
> Array ( [X-Forwarded-For] => 57.73.33.1 [Cookie] =>
> `ci_session=kd817592v16s0p5b2f502hg39rs7olnu;
> csrf_cookie=22a1c908f3f036c90c2d0bf0f9b19497 [Accept-Language] =>
> en-GB,en-US;q=0.8,en;q=0.6 [Accept-Encoding] => gzip, deflate
> [Referer] => http://testurl.com/xxx [X-Requested-With] =>
> XMLHttpRequest [Accept] => */* [Content-Type] =>
> application/x-www-form-urlencoded; charset=UTF-8 [User-Agent] =>
> Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like
> Gecko) Chrome/54.0.2840.99 Safari/537.36 [Origin] =>
> http://testurl.com[Cache-Control] => no-cache [Pragma] => no-cache
> [Content-Length] => 325 [Connection] => close [Host] => testurl.com )`
How can i get that customer header in PHP? I am using codeigniter,
I only got output by below,
$.ajaxSetup( {
data: {csrf_token : csrf},
headers: {"csrf-token" : csrf, "csrf_token1" : csrf}
});
It will not print values with _ name but can print with - names.
Csrf-Token : "22a1c908f3f036werc90c2d0bf0f9b19497"
Use this
$headers = $this->input->request_headers();
link : https://www.codeigniter.com/user_guide/libraries/input.html#CI_Input::get_request_header

Ajax setRequestHeader, i can't get values on the server side

I am sending request header using XMLHttpRequest :
liveXhr.open("GET", url, true);
liveXhr.setRequestHeader("keychain_id", signatureKEYCHAINID);
liveXhr.setRequestHeader("timestamp", signatureTS);
liveXhr.setRequestHeader("signature", signature);
liveXhr.send();
On my localhost everything is fine, when i log :
error_log(print_r(apache_request_headers(), true));
I have this :
[Host] => localhost
[Connection] => keep-alive
[Pragma] => no-cache
[Cache-Control] => no-cache
[timestamp] => 1478279032
[signature] => abcd
[keychain_id] => abcd
[User-Agent] => Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 ( KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
[Content-Type] => text/plain
I can get the values for timestamp, signature, keychain_id
On my preprod server for the same process :
...
[Access-Control-Request-Headers] => keychain_id, signature, timestamp
...
I can't get the values of timestamp, signature, keychain_id.
Is it an apache setting concern or something else ?
Try:
//array
$requestHeaders = apache_request_headers();
//get array item by name
$keyChainId = $requestHeaders['keychain_id'];
$timestamp = $requestHeaders['timestamp'];
$signature = $requestHeaders['signature'];
//print items
echo "- keychain_id = $keyChainId";
echo "\n- timestamp = $timestamp";
echo "\n- signature = $signature";
[Edited]
Try:
//not underscore
liveXhr.setRequestHeader("keychainid", KEYCHAINID);
...
//prefix HTTP_
var_dump($_SERVER['HTTP_TIMESTAMP']);
var_dump($_SERVER['HTTP_SIGNATURE']);
var_dump($_SERVER['HTTP_KEYCHAINID']);

Pick off Authentication header PHP

I am sending a token within the headers of each request, when I do a print_r(apache_request_headers()); I get ...
[Host] => 192.168.100.100
[Connection] => keep-alive
[Authorization] =>d868cbf31f676130649fbfd7fff64a70cc071cd0fc8afa676b ...
[Origin] => null
[User-Agent] => Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
[Accept] => */*
[Accept-Encoding] => gzip, deflate, sdch [Accept-Language] => en-US,en;q=0.8 )
I have tried echo $_SERVER['Authorization']; but get a an error Undefined index: Authorization.
How do I get the token.
You can either use array dereferencing (PHP >= 5.4), e.g.
echo apache_request_headers()["Authorization"];
Or assign it to a variable an then access it, e.g.
$headers = apache_request_headers();
echo $headers["Authorization"];
Try this, it is Server Independent
$header = getallheaders();
echo $header['Authorization'];

cURL works from Terminal, but not from PHP

I'm running into a rather strange issue.
I'm trying to log into a remote moodle install using curl from PHP.
I have a curl command, which works perfectly in the Terminal.
When I translate the same thing into PHP, it works, but it just doesn't login. The exact same value which successfully login via terminal, somehow trips up the login system via PHP and it doesn't login. Instead, it returns the login page again.
My cURL command (data section ommitted as it has my username and password):
curl 'http://moodle.tsrs.org/login/index.php'
-H 'Pragma: no-cache'
-H 'Origin: http://moodle.tsrs.org'
-H 'Accept-Encoding: gzip, deflate'
-H 'Accept-Language: en-US,en;q=0.8'
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36'
-H 'Content-Type: application/x-www-form-urlencoded'
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
-H 'Cache-Control: no-cache'
-H 'Referer: http://moodle.tsrs.org/login/index.php'
-H 'Cookie: MoodleSession=ngcidh028m37gm8gbdfe07mvs7; MOODLEID_=%25F1%25CD%2519D%25B2k%25FE%251D%25EFH%25E5t%25B1%2503%258E; MoodleSessionTest=NhzaTNij6j; _ga=GA1.2.925953522.1416155774; _gat=1; __utmt=1; __utma=147409963.925953522.1416155774.1416642544.1416692798.3; __utmb=147409963.1.10.1416692798; __utmc=147409963; __utmz=147409963.1416155774.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)'
-H 'Connection: keep-alive'
The corresponding PHP code:
function login() {
$username = $_POST['username'];
$password = $_POST['password'];
if(!isset($_POST['username']) || !isset($_POST['password'])) {
echo "No login data received";
return;
}
$creq = curl_init();
$data = array('username' => $username, 'password' => $password, 'testcookies'=> '1');
$headers = array('Pragma: no-cache', 'Origin: http://moodle.tsrs.org', 'Accept-Encoding: ', 'Accept-Language: en-US,en;q=0.8', 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36', 'Content-Type: application/x-www-form-urlencoded', 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Cache-Control: no-cache', 'Cookie: MoodleSession=ngcidh028m37gm8gbdfe07mvs7; MOODLEID_=%25F1%25CD%2519D%25B2k%25FE%251D%25EFH%25E5t%25B1%2503%258E; MoodleSessionTest=NhzaTNij6j; _ga=GA1.2.925953522.1416155774; _gat=1; __utmt=1; __utma=147409963.925953522.1416155774.1416642544.1416692798.3; __utmb=147409963.1.10.1416692798; __utmc=147409963; __utmz=147409963.1416155774.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)', 'Connection: keep-alive' );
curl_setopt_array($creq, array(
CURLOPT_URL => 'http://moodle.tsrs.org/login/index.php',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_ENCODING => '',
CURLINFO_HEADER_OUT => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_FOLLOWLOCATION => false
));
$output = curl_exec($creq);
echo print_r(curl_getinfo($creq));
echo "\n" . $output . "\n";
}
And the output of curlinfo:
Array
(
[url] => http://moodle.tsrs.org/login/index.php
[content_type] => text/html; charset=utf-8
[http_code] => 200
[header_size] => 541
[request_size] => 945
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 1.462409
[namelookup_time] => 0.002776
[connect_time] => 0.330766
[pretransfer_time] => 0.330779
[size_upload] => 365
[size_download] => 8758
[speed_download] => 5988
[speed_upload] => 249
[download_content_length] => -1
[upload_content_length] => 365
[starttransfer_time] => 0.694866
[redirect_time] => 0
[certinfo] => Array
(
)
[primary_ip] => 125.22.33.149
[redirect_url] =>
[request_header] => POST /login/index.php HTTP/1.1
Host: moodle.tsrs.org
Pragma: no-cache
Origin: http://moodle.tsrs.org
Accept-Language: en-US,en;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Cache-Control: no-cache
Cookie: MoodleSession=ngcidh028m37gm8gbdfe07mvs7; MOODLEID_=%25F1%25CD%2519D%25B2k%25FE%251D%25EFH%25E5t%25B1%2503%258E; MoodleSessionTest=NhzaTNij6j; _ga=GA1.2.925953522.1416155774; _gat=1; __utmt=1; __utma=147409963.925953522.1416155774.1416642544.1416692798.3; __utmb=147409963.1.10.1416692798; __utmc=147409963; __utmz=147409963.1416155774.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Connection: keep-alive
Content-Length: 365
Expect: 100-continue
Content-Type: application/x-www-form-urlencoded; boundary=----------------------------83564ee60d56
)
Does anyone know any possible reason for this? I've tried swapping out the hard coded cookie with COOKIEFILE and COOKIEJAR, but it doesn't change anything.
This could have been debugged better by seeing everything that was actually done by cURL. This is done by adding the verbose flag to the command: -v.
$ curl localhost/login [...] -v
We can get the same output from PHP's curl by adding the CURLOPT_VERBOSE option. Note that by adding this line you are instructing cURL to output the same information to STDOUT - it will not be returned and content will not be sent to the browser, so this must be debugged in the terminal.
curl_setopt($curl, CURLOPT_VERBOSE, 1);
By doing it this way, you can get a consistent and comparable output of both HTTP requests, it should look sommthing like this:
POST / HTTP/1.1
Host: localhost:3000
Pragma: no-cache
Origin: http://moodle.tsrs.org
Accept-Language: en-US,en;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Cache-Control: no-cache
Cookie: MoodleSession=ngcidh028m37gm8gbdfe07mvs7; MOODLEID_=%25F1%25CD%2519D%25B2k%25FE%251D%25EFH%25E5t%25B1%2503%258E; MoodleSessionTest=NhzaTNij6j; _ga=GA1.2.925953522.1416155774; _gat=1; __utmt=1; __utma=147409963.925953522.1416155774.1416642544.1416692798.3; __utmb=147409963.1.10.1416692798; __utmc=147409963; __utmz=147409963.1416155774.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Connection: keep-alive
Content-Length: 250
Expect: 100-continue
Content-Type: application/x-www-form-urlencoded; boundary=------------------------b4d79f17a3887f2d
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: application/json; charset=utf-8
< Content-Length: 2
< ETag: W/"2-mZFLkyvTelC5g8XnyQrpOw"
< Date: Thu, 22 Dec 2016 19:13:40 GMT
< Connection: keep-alive
Left: Command line cURL as provided in the question (with extra -v flag)
Right: PHP cURL as posted in the question (with CURLOUT_VERBOSE enabled)
As you can see, the headers aren't the same, and this makes that clear. The PHP invocation is missing Accept-Encoding and Referer headers.
If that didn't turn up anything, let's try changing some more cURL settings in PHP back to the original cURL defaults.
Internally, PHP opts to override some defaults in cURL without telling you. While these settings should be fine, let's change them back by explicitly reseting them back to cURL defaults:
curl_setopt($curl, CURLOPT_DNS_CACHE_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_DNS_USE_GLOBAL_CACHE, 0);
curl_setopt($curl, CURLOPT_MAXREDIRS, -1);
curl_setopt($curl, CURLOPT_NOSIGNAL, 0);
Use http_build_query on the $data array before passing to curl to avoid Content-Type: application/x-www-form-urlencoded; boundary=---. This also ensures to encode any special characters from the password.
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
Reshape your curl requests as follows:
Make a GET request to the login page with pointing a cookie file at $cookies = '/tmp/some/dir/xyz.cookie.txt'. Make sure using full path for cookie name. And then close the curl handle. This will store the cookie in cookie file.
$creq = curl_init();
curl_setopt_array($creq, array(
CURLOPT_URL => 'http://moodle.tsrs.org/login/index.php',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLINFO_HEADER_OUT => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_COOKIEJAR => $cookies // save cookie
));
$output = curl_exec($creq);
curl_close($creq);
Now make the POST request with second curl request. This time point the same cookie file with COOKIEFILE option.
$creq = curl_init();
curl_setopt_array($creq, array(
CURLOPT_URL => 'http://moodle.tsrs.org/login/index.php',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_ENCODING => '',
CURLINFO_HEADER_OUT => true,
CURLOPT_POSTFIELDS => http_build_query ($data),
CURLOPT_HTTPHEADER => $headers,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_COOKIEJAR => $cookies, // save cookie
CURLOPT_COOKIEFILE => $cookies // load cookie
);
$output = curl_exec($creq);
curl_close($creq);
It can happen sometimes the server look for the cookie when a login request made (to ensure that the request came after visiting the login page).
Most likely your problem is related to HTTP header Expect: 100-continue that cURL sends by default for each POST request.
The Expect: 100-continue header is used in POST requests containing big data when client is not sure that server will accept such request. In this case client first sends request with only headers including Expect: 100-continue and, if the server's response is successful, send the same request with body (POST data).
The problem is that not all web servers handle this header correctly. In such cases sending this header is undesired.
The solution is manually remove Expect header from sending headers by passing array('Expect:') to CURLOPT_HTTPHEADER option.
In your case you can simply add 'Expect:' string to $headers array:
$headers[] = 'Expect:';
I solved the issue by setting a User-Agent
$headers = array(
'Accept: */*',
'User-Agent: curl/7.68.0',
'Accept-Encoding: deflate,gzip,br',
'Content-Type:application/json',
);
I suspect your first attempt using the curl command is using the GET method in the index.php file. I suggest you enable --trace-ascii on your first curl request in the command line and see whether a GET request is being made by the page or not. If yes, you should change your PHP script which is using the POST method. If you change the CURLOPT_POST to false, the PHP script should work.

Categories