I'm trying to send a HTTP POST request through curl in php to the new Grandstream API and I'm getting the same error each time. I have to say I'm currently able to do GET requests successfully but the problems start when a body has to be send in POST.
$gdms_domain = "eu.gdms.cloud";
$timestamp = round(microtime(true)*1000);
$params_data = array(
'access_token' => '*********',
'client_id' => '*****',
'client_secret' => '************',
'timestamp' => $timestamp
);
$body_data = array(
'pageSize' => "",
'pageNum' => "",
'order' => "",
'type' => "",
'orgId' => ""
);
$params = http_build_query($params_data);
$body = json_encode($body_data);
$signature = hash("sha256","&".$params."&");
$payload_data = array(
'access_token' => $token,
'signature' => $signature,
'timestamp' => $timestamp
);
$payload = http_build_query($payload_data);
$ch = curl_init();
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_URL => 'https://'.$gdms_domain.'/oapi/v1.0.0/device/list'."?".$payload,
CURLOPT_HTTPHEADER => array(
"Content_type: application/json"
)
);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
if(curl_error($ch)){
echo 'Request Error:'.curl_error($ch);
}else{
$response = json_decode($response);
print_r($response);
return $response;
}
curl_close($ch);
The error that is returned is:
(
[data] =>
[msg] => bad signature
[retCode] => 40003
)
The API documentation is in here GDMS API. I tried to build the signature in both possible ways according to the docs and send the body in different ways.
Thank you
You should add the hashed body to the signature.
$body_signature = hash("sha256",$body);
Then final signature should be
$signature = hash("sha256","&".$params."&".$body_signature."&");
Related
I'm performing a POST request to a REST Service that requires an OAuth 2.0 authorization.
In Postman everything works perfectly fine since enabling the "Follow Authorization header" option so the auth header will be retained after a redirection.
However I dont know the equivalent to that attribute for a CURL request in PHP. So therefore I still get the following error: "Session expired or invalid".
Does anyone know how to successfully keep the auth header after a redirection in PHP cURL?
This is my php code:
$token = $this->getToken();
$url = "XXX";
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
,
curl_setopt($curl, CURLOPT_POSTFIELDS, array(
'client_id' => 'XXX',
'client_secret' => 'XXX',
'username' => 'XXX',
'password' => 'XXX',
'grant_type' => 'password',
'redirect_uri' => 'XXX'
)))
));
$response = curl_exec($curl);
var_dump('TOKEN: ' . $token);
var_dump($url);
var_dump(curl_getinfo($curl));
if (curl_errno($curl)) {
var_dump('Error:' . curl_error($curl));
} else {
var_dump("SUCCESS! ");
var_dump($response);
}
You cannot do this:
curl_setopt($curl, CURLOPT_POSTFIELDS, array(
'client_id' => 'XXX',
'client_secret' => 'XXX',
'username' => 'XXX',
'password' => 'XXX',
'grant_type' => 'password',
'redirect_uri' => 'XXX'
You already did this: URLOPT_POSTFIELDS => json_encode($data),
And you cannot use an array if you want to keep the Content-Type: application/json.
When you use an array for POSTFIELDS, curl will override the content type with Content-Type: application/x-www-form-urlencoded
I sometimes use file_get_content() with a context.
This is an easy way (without SSL) to get the headers and post data right.
Keeping mind that file_get_content() has some of the same idiosyncrasies as curl. The context has file_get_content() which populates the Body.
<?php
header("Content-Type: text/plain,UTF-8");
$jsn = file_get_contents('json.jsn');
$postdata = http_build_query(
array(
'json' => $jsn,
)
);
$opts = array('http' =>
array(
'method' => 'PUT',
'header' => 'Content-type: application/json',
'content' => $jsn //useing JSON rather than $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
echo $result;
I'm trying to publish new podcasts via the api, I've successfully upload the mp3 and jpg, which gives 600 seconds to then publish. The podcast 'type' is required and one of the acceptable values is 'public. Here the response:
{"error":"input_params_invalid","error_description":"Episode type is invalid."}
I'm doing this in PHP. I've been successfully connecting to the API, it is not a token issue.
$params = [
'access_token'=> $token,
'type' => 'public',
'apple_episode_typeoptional' => 'full',
'status' => 'publish',
'media_key' => $files['audio'],
'logo_key' => $files['image'],
'title' => 'Good day',
'content' => 'Time you <b>enjoy</b> wasting, was not wasted.'
];
$params = http_build_query($params);
// . '?' . $params,
// CURLOPT_POSTFIELDS => $params
$options = [
CURLOPT_URL => $url . '?' . $params,
CURLOPT_POST => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_SSL_VERIFYPEER => FALSE
];
$response = $this->getPodbean($options);
UPDATE:
This is what is holding me up. I don't think I have converted curl -v -H "Content-Type: image/jpeg" -T /your/path/file.ext "{presigned_url}" correctly. I added CURLOPT_USERPWD because without it I was getting a 403, now I get 400. I added token for good measure but it doesn't seem to affect anything one way or the other.
$imageMime = mime_content_type($image_path);
$filename = basename($image_path);
$cfile = curl_file_create($image_path, $imageMime, $filename);
//Open the file using fopen.
$fileHandle = fopen($image_path, 'r');
$options = [
CURLOPT_URL => $presigned_url,
CURLOPT_USERPWD => "$this->client_id:$this->client_secret",
CURLOPT_POSTFIELDS => http_build_query(['image_upload' => $cfile, 'access_token'=> $token]),
CURLOPT_POST => TRUE,
CURLOPT_HTTPHEADER => http_build_query(['Content-Type' => $imageMime]),
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_SSL_VERIFYPEER => FALSE
];
$this->getPodbean($options);
I tried to send a POST request from WordPress to an external API (assign a tag to an user in a CRM system). When I used cURL, everything was OK. Here is the cURL code:
function my_function () {
$body = array ( 'tags' => array ( array (
'email' => 'xxx#gmail.com',
'tag' => 'Customer5'
))
);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "$api_url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode($body, true),
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json",
"User-Agent: Your App Name (www.yourapp.com)",
"Authorization: Basic xxxxxx"
),
));
$response = curl_exec($curl);
curl_close($curl);
var_dump($response);
}
add_action( 'init', 'my_function');
But then I switched to use wp_remote_post, I got a "415 - Unsupported Media Type" response.
$body = array ( 'tags' => array (
array(
'email' => 'xxx#gmail.com',
'tag' => 'Customer5'
))
);
$headers = array (
'Content-Type' => 'application/json',
'User-Agent' => 'Your App Name (www.yourapp.com)',
'Authorization' => 'Basic xxxxxx',
);
$request = wp_remote_post('$api_url', $arg );
$arg = array (
'header' => $headers,
'body' => json_encode($body, true),
'method' => 'POST',
'sslverify' => false,
);
echo '<pre>';
print_r($request);
echo '</pre>';
I tried a lot of modifications (changed associative array format to key:value pair, add AddType to htaccess file...), but nothing worked. Please help, I'm stuck
Excerpt from KeyCDN:
A 415 Unsupported Media Type error occurs when the origin server
refuses a particular request since the resource is in a format that is not supported by the server for the HTTP
method
used. This unsupported format type issue can be caused by what is
defined in the resource's Content-Type or Content-Encoding
headers.
And in your case, the error happened most likely because your remote request sent the wrong Content-Type header — which defaults to application/x-www-form-urlencoded when the HTTP method is POST.
And yes, you did include the right Content-Type value in your $headers array. But unfortunately in your $arg array which you passed to wp_remote_post(), you used the wrong array key — header, which should actually be headers (note the "s").
So use headers and not header, just as you can see below:
$api_url = 'your API URL';
$body = array(
'tags' => array(
array(
'email' => 'xxx#gmail.com',
'tag' => 'Customer5',
),
),
);
$headers = array(
'Content-Type' => 'application/json',
'User-Agent' => 'Your App Name (www.yourapp.com)',
'Authorization' => 'Basic xxxxxx',
);
$arg = array(
'headers' => $headers, // good
// 'header' => $headers, // bad; i.e. wrong array key ('header')
'body' => json_encode( $body ),
// 'method' can be omitted since you're using wp_remote_post()
'method' => 'POST',
'sslverify' => false,
);
$request = wp_remote_post( $api_url, $arg );
// ..if the response still isn't good, what's the output of this:
var_dump( $request );
When trying to revoke the oauth access_token for Box, I get the error : Client id was not found in the headers or body
This is the curl-command (which works fine) :
curl https://api.box.com/oauth2/revoke -d 'client_id=CLIENT_ID&client_secret=CLIENT_SECRET&token=access_token' -X POST
When trying the same with php curl, I get the error.
<?php
$revokeurl="https://api.box.com/oauth2/revoke";
$dataq = array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'token' => $access_token
);
$dataqjson= json_encode($dataq);
$headers=array(
"Content-Type: application/json"
);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $revokeurl,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $dataqjson,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_SSL_VERIFYHOST => FALSE
));
$response = curl_exec($curl);
$json_response = json_decode( $response, TRUE );
curl_close($curl);
?>
Why is my POST with json body not correct ?
Data should be set as application/x-www-form-urlencoded rather than JSON-encoded. Example:
<?php
$revokeurl = "https://api.box.com/oauth2/revoke";
$dataq = array(
'client_id' => 'client_id',
'client_secret' => 'client_secret',
'token' => 'access_token',
);
$curl = curl_init();
curl_setopt_array(
$curl,
array(
CURLOPT_URL => $revokeurl,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => http_build_query($dataq),
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false
)
);
$response = curl_exec($curl);
$json_response = json_decode($response, false);
print_r($json_response);
curl_close($curl);
I'm making small steps into this project I am working on. Now creating and registering a webhook. I'm getting the below response:
400 - Invalid Header
I have tried the following code:
// Send a request to register a web hook
$http2 = new Client('https://api.bigcommerce.com', array(
'request.options' => array(
'exceptions' => false,
'headers' => array(
'X-Auth-Client' => $client_id,
'X-Auth-Token' => $access_token,
'Content-Type' => 'application/json',
'X-Custom-Auth-Header' => $access_token,
)
)
));
$request = $http2->post('/'.$store_hash.'/v2/hooks', null, array(
'scope' => 'store/order/*',
'destination' => 'https://example.com/process_order.php',
'is_active' => true
));
$response = $request->send();
$body = $response->getBody(true);
var_dump($body);
echo '<p>Status Code: ' . $response->getStatusCode() . '</p>';
... and
// Send a request to register a web hook
$http2 = new Client('https://api.bigcommerce.com', array(
'request.options' => array(
'exceptions' => false,
'headers' => array(
'X-Auth-Client' => $client_id,
'X-Auth-Token' => $access_token,
'Content-Type' => 'application/json',
)
)
));
$request = $http2->post('/'.$store_hash.'/v2/hooks', null, array(
'scope' => 'store/order/*',
'headers' => array(
'X-Custom-Auth-Header' => $access_token,
),
'destination' => 'https://example.com/process_order.php',
'is_active' => true
));
$response = $request->send();
$body = $response->getBody(true);
var_dump($body);
echo '<p>Status Code: ' . $response->getStatusCode() . '</p>';
I am working with the documentation here:
https://developer.bigcommerce.com/api/stores/v2/webhooks#create-a-hook
However, I can't seem to work out what {secret_auth_password} is as well? The documentation doesn't explain this. I am sending the Client ID and Client Header as part of the headers as well.
Still getting Invalid Header as a response.
I am using Guzzle.
Can anyone assist me on this please?
I have finally worked out what I did wrong after numerous attempts.
Answer: send the data in JSON format.
Resolved Code:
// Send a request to register a web hook
$http3 = new Client('https://api.bigcommerce.com', array(
'request.options' => array(
'exceptions' => false,
'headers' => array(
'X-Auth-Client' => $client_id,
'X-Auth-Token' => $access_token,
'Content-Type' => 'application/json',
'Accept' => 'application/json',
)
)
));
$request = $http3->post('/'.$store_hash.'/v2/hooks', null, json_encode(array(
'scope' => 'store/order/statusUpdated',
'destination' => 'https://example.com/process_order.php',
)));
$response = $request->send();