Using the following code to try and create the signature and get the bearer token.
<?php
$tm=time();
$param_str = "grant_type=client_credentials&oauth_consumer_key=xxxx&oauth_nonce=xxx&oauth_signature_method=HMAC-SHA256&oauth_timestamp=".$tm."&oauth_version=1.0";
//die($param_str);
$base_str = "POST&" .urlencode("https://account.api.here.com/oauth2/token") . "&" . urlencode($param_str);
//die($base_str);
$sign_key = urlencode("xxxxxxxxxxxxxxxxxxxxxxxxx")."&";
$signature= hash_hmac("sha256",$base_str,$sign_key);
$url = "https://account.api.here.com/oauth2/token";
$ch = curl_init( $url );
$headers = [
'Content-Type: application/x-www-form-urlencoded',
'Authorization: OAuth oauth_consumer_key="xxx",oauth_nonce="xxx",oauth_signature="'.$signature.'",oauth_signature_method="HMAC-SHA256",oauth_timestamp="'.$tm.'",oauth_version="1.0"',
'Cache-Control: no-cache'
];
$payload="grant_type=client_credentials";
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
# Return response instead of printing.
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
# Send request.
$result = curl_exec($ch);
curl_close($ch);
?>
Tried various combinations. Getting the same error (Signature mismatch. Authorization signature or client credential is wrong). Even tried copying the exact url encoded string from the document, replacing relevant information and still not working. Is there something I am not understanding at all from the documentation or something I am missing here in my code.
The reason for signature mismatch is that the one you created is different than the one server created. Check the following –
Did you convert the signing key and base string into bytes before
passing it to HMAC-SHA256 hashing algorithm.
Did you convert the output of HMAC-SHA256 hashing algorithm into
base64 string.
also check this link if this can help you.
Related
I'm trying to make batch request from a wordpress plugin to the gmail API to download multiple messages at once. I can get them using curl function:
$BOUNDARY='gmail-message-boundary';
$body= "";
foreach ($message_ids as $message_id) {
$body.= "--$BOUNDARY\n";
$body.= "Content-Type: application/http\n\n";
$body.= 'GET https://www.googleapis.com/gmail/v1/users/'.$email_id.
'/messages/'.$message_id->id.'?metadataHeaders=From&format=metadata&key='.urlencode($gmail_api_key)."\n\n";
$post_body .= "--$BOUNDARY--\n";
$headers = [
'Content-type: multipart/mixed; boundary='.$BOUNDARY,
'Authorization: OAuth '.$auth_token
];
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL, 'https://www.googleapis.com/batch/gmail/v1' );
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl,CURLOPT_CONNECTTIMEOUT , 60 ) ;
curl_setopt($curl, CURLOPT_TIMEOUT, 60 ) ;
curl_setopt($curl,CURLOPT_POSTFIELDS , $body);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
$res= curl_exec($curl);
curl_close($curl);
this code works perfectly but I want to achieve the same result using only worpdress functions. Unfortunately, when I'm trying to make the request using wp_remote_post function I'm getting this response:
{
"headers":{
},
"body":"{\n \"error\": {\n \"code\": 400,\n \"message\": \"Failed to get multipart boundary.\",\n \"status\": \"INVALID_ARGUMENT\"\n }\n}\n",
"response":{
"code":400,
"message":"Bad Request"
},
"cookies":[
],
"filename":null,
"http_response":{
"data":null,
"headers":null,
"status":null
}
}
Does anyone knows how to use wordpress functions to make batch http request?
To get the statuscode of a website with curl you can use the CURLOPT NOBODY.
Example:
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://www.example.com');
curl_setopt($curl , CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$status = curl_exec($curl);
curl_close($curl);
Is the following example with Guzzle as http library the same:
$guzzle = new Client();
$req = $guzzle->createRequest('GET', 'http://www.example.com');
$result = $guzzle->send($req);
$status = $result->getStatusCode();
My goal is to perform a curl/guzzle request without getting the body. Will that request with Guzzle only fetch the status code without wasting bandwith on other data?
In order to get status code of the response without downloading the whole content, you should use "head" method:
$client = new \GuzzleHttp\Client();
$response = $client->head('http://example.com/');
echo $response->getStatusCode();
I created a valid ticket using a webservice call...code shown below
$url="http://serverip:port/alfresco/service/api/login?u=xxx&pw=xxx";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$response =curl_exec($ch);
Now using this ticket i want to authenticate alfresco without again entering username and password.Also i want to create a valid cookie JSESSIONID inside browser with this ticket...Is it feasible??
my purpose is to integrate a php application with alfresco....php application already has an authentication system...so i want to bypass the authentication of alfresco
You need to append below parameter
alf_ticket="TICKET_WHICH_YOU_GET"
for further authentication.
Finally i resolved the issue by calling the login page url http://ip:port/share/page/ via Curl with login parameters(username and pwd)...I got JsessionId as response from curl...Now i took that JsessionId and set inside the browser...so wen u click http://ip:port/share/page/ the login page is bypassed
As per your suggestion, we are tried with below curl call but their is no JsessionId in response. can you please check and let me know the resolution
$post = [
'username' => 'user',
'password' => 'pass',
];
$ch = curl_init('http://ip:port/share/page/dologin/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
var_dump($response);
please suggest with the solution
I don't use javascript, so I'm completely new to it.
I have a link where I want to login per POST request. Just send a POST request with pre-defined correct login and password and get the data on the next page.
I'm using developer mode in Chrome to look on the requests sent by browser.
But when I type in correct combination of username and password, I don't see a single POST request, only GETs.
With incorrect username and password I'm able to see a POST request with following Form Data values:
xjxfun:_validateLogin
xjxr:1389197444586
xjxargs[]:<xjxobj>
<e><k>Username</k><v>SmyUsername</v></e>
<e><k>Password</k><v>SmyPassword</v></e>
<e><k>Autologin</k><v>S1</v></e>
<e><k>REFERER</k><v>Sdailyfield</v></e>
</xjxobj>
Here I typed in myUsername for Username and myPassword for Password.
My question is
What POST request do I need to send to this server to imitate form filling and submitting?
Thank you for answering. The best answer you can give is to describe the POST request with necessary data/headers/values, so that I can prove it fast in some REST client in browser
Here is the data I got sent from a valid login:
xjxfun:_validateLogin
xjxr:1389422948740
xjxargs[]:<xjxobj><e><k>Username</k><v>S<![CDATA[myemailhere]]></v></e><e><k>Password</k><v>Smypasswordhere</v></e><e><k>Autologin</k><v>S1</v></e><e><k>REFERER</k><v>Sdailyfield</v></e></xjxobj>
And this is what I got returned:
<?xml version="1.0" encoding="utf-8" ?><xjx><cmd cmd="js">Slocation.href = 'sudoku_des_tages.htm';</cmd></xjx>
By the way, this was a POST request.
I think the reason that you can only see GET requests, was because an HTTP redirect occurred on the server-side with your authentication details, and that request (as with all page requests) is a GET request, which is probably why you can only see GET requests with successful authentication.
Update: From what I understand, you are sending the values as header values (in others words, alongside Content-Type and the like), while you should send them in the post formdata. This is why you are finding your answer.
You can always use CURL :
$fields_string = '';
$url = "yourProceesfileURL";
$userdata = array(
'email' => youremail,
'password' => yourpassword
);
foreach ($userdata as $key => $value) {
$fields_string .= $key . '=' . $value . '&';
}
rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($userdata));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
$result = curl_exec($ch);
curl_close($ch);
:)
Note: This solution was suggested when the question was tagged with JavaScript and PHP and without Objective-C.
You can use JQuery to simulate the form filling like this:
$(function(){
$('#Username').val('MyUsername');
$('#Password').val('MyPassword');
$('input[type=submit]').trigger("click");
});
Working example here
First you want to set the values by getting the input element with his id and then setting his value. Once you finish updating all the requested values just trigger the submit button.
This will simulate you filling the form and submitting it. To do this automatically I would use PHP to get the content of the page and then firing the JQuery function:
echo file_get_contents("http://www.sudoku-knacker.de/anmeldung.htm?ref=dailyfield");
I'm POSTing data to an external API (using PHP, if it's relevant).
Should I URL-encode the POST variables that I pass?
Or do I only need to URL-encode GET data?
UPDATE: This is my PHP, in case it is relevant:
$fields = array(
'mediaupload'=>$file_field,
'username'=>urlencode($_POST["username"]),
'password'=>urlencode($_POST["password"]),
'latitude'=>urlencode($_POST["latitude"]),
'longitude'=>urlencode($_POST["longitude"]),
'datetime'=>urlencode($_POST["datetime"]),
'category'=>urlencode($_POST["category"]),
'metacategory'=>urlencode($_POST["metacategory"]),
'caption'=>($_POST["description"])
);
$fields_string = http_build_query($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
General Answer
The general answer to your question is that it depends. And you get to decide by specifying what your "Content-Type" is in the HTTP headers.
A value of "application/x-www-form-urlencoded" means that your POST body will need to be URL encoded just like a GET parameter string. A value of "multipart/form-data" means that you'll be using content delimiters and NOT url encoding the content.
This answer has a much more thorough explanation if you'd like more information.
Specific Answer
For an answer specific to the PHP libraries you're using (CURL), you should read the documentation here.
Here's the relevant information:
CURLOPT_POST
TRUE to do a regular HTTP POST.
This POST is the normal application/x-www-form-urlencoded kind, most commonly used by HTML forms.
CURLOPT_POSTFIELDS
The full data to post in a HTTP "POST" operation. To post a file, prepend a filename with # and use the full path. The filetype can be explicitly specified by following the filename with the type in the format ';type=mimetype'. This parameter can either be passed as a urlencoded string like 'para1=val1¶2=val2&...' or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data. As of PHP 5.2.0, value must be an array if files are passed to this option with the # prefix.
#DougW has clearly answered this question, but I still like to add some codes here to explain Doug's points. (And correct errors in the code above)
Solution 1: URL-encode the POST data with a content-type header :application/x-www-form-urlencoded .
Note: you do not need to urlencode $_POST[] fields one by one, http_build_query() function can do the urlencoding job nicely.
$fields = array(
'mediaupload'=>$file_field,
'username'=>$_POST["username"],
'password'=>$_POST["password"],
'latitude'=>$_POST["latitude"],
'longitude'=>$_POST["longitude"],
'datetime'=>$_POST["datetime"],
'category'=>$_POST["category"],
'metacategory'=>$_POST["metacategory"],
'caption'=>$_POST["description"]
);
$fields_string = http_build_query($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
Solution 2: Pass the array directly as the post data without URL-encoding, while the Content-Type header will be set to multipart/form-data.
$fields = array(
'mediaupload'=>$file_field,
'username'=>$_POST["username"],
'password'=>$_POST["password"],
'latitude'=>$_POST["latitude"],
'longitude'=>$_POST["longitude"],
'datetime'=>$_POST["datetime"],
'category'=>$_POST["category"],
'metacategory'=>$_POST["metacategory"],
'caption'=>$_POST["description"]
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
Both code snippets work, but using different HTTP headers and bodies.
curl will encode the data for you, just drop your raw field data into the fields array and tell it to "go".
Above posts answers questions related to URL Encoding and How it works, but the original questions was "Should I URL-encode POST data?" which isn't answered.
From my recent experience with URL Encoding, I would like to extend the question further.
"Should I URL-encode POST data, same as GET HTTP method. Generally, HTML Forms over the Browser if are filled, submitted and/or GET some information, Browsers will do URL Encoding but If an application exposes a web-service and expects Consumers to do URL-Encoding on data, is it Architecturally and Technically correct to do URL Encode with POST HTTP method ?"