I'm trying to use Application Only Authentication, as described here:
https://developer.twitter.com/en/docs/basics/authentication/overview/application-only
I'm using the following PHP code to do so.
if(empty($_COOKIE['twitter_auth'])) {
require '../../social_audit_config/twitter_config.php';
$encoded_key = urlencode($api_key);
$encoded_secret = urlencode($api_secret);
$credentials = $encoded_key.":".$encoded_secret;
$encoded_credentials = base64_encode($credentials);
$request_headers = array(
'Host: api.twitter.com',
'User-Agent: BF Sharing Report',
'Authorization: Basic '.$encoded_credentials,
'Content-Type: application/x-www-form-urlencoded;charset=UTF-8',
'Content-Length: 29',
'Accept-Encoding: gzip'
);
print_r($request_headers);
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, 'https://api.twitter.com/oauth2/token');
curl_setopt($ch, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');
$attempt_auth = curl_exec($ch);
print_r($attempt_auth);
}
It should return JSON with the token in it, but instead it returns gobbledygook, as seen in the image below:
I'm sure I'm missing some very simple step, where am I going wrong?
If I send the curl request without the headers, it returns an error in JSON format as expected, so is there something wrong with my headers?
You have few options here. Instead of setting header directly, use below
curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
If you set header directly then you should use
print_r(gzdecode($attempt_auth));
See below thread as well
Decode gzipped web page retrieved via cURL in PHP
php - Get compressed contents using cURL
Related
I'm using the below code to upload an MP4 file to a web service, using PHP cURL.
I've specified the 'Content-Type' as 'video/mp4', in CURLOPT_HTTPHEADER.
Unfortunately, having uploaded the file, the 'Content-Type' stored for it in the service displays as: "content_type":"video/mp4; boundary=----WebKitFormBoundaryfjNZ5VkJS8z3CB9X"
As you can see, the 'boundary' has been inserted into the 'content_type'.
When I then download the file, it fails to play, with a 'file unsupported/file extension incorrect/file corrupt' message.
$authorization = "Authorization: Bearer [token]";
$args['file'] = curl_file_create('C:\example\example.mp4','video/mp4','example');
$url='[example web service URL]';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data', 'Accept: application/vnd.mendeley-content-ticket.1+json', $authorization));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS , $args);
$response = curl_exec($ch); // URL encoded output - needs to be URL encoded to get the HREF link header
curl_close($ch);
Would be extremely grateful for any help, advice or pointers!
Maybe the API doesn't expects a POST multipart, but the actual contents in the body itself:
Ref: How to POST a large amount of data within PHP curl without memory overhead?
You need to use PUT method for the actual contents of the file to go inside the body - if you use POST, it will try to send as a form.
$authorization = "Authorization: Bearer [token]";
$file = 'C:\example\example.mp4';
$infile = fopen($file, 'r');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.mendeley.com/file_contents");
curl_setopt($ch, CURLOPT_PUT, 1 ); // needed for file upload
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file));
curl_setopt($ch, CURLOPT_INFILE, $infile);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST' );
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: video/mp4', 'Accept: application/vnd.mendeley-content-ticket.1+json', $authorization));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec ($ch);
I have the same problem calling a Openai API from PHP curl.
I send options: Content-Type and Authorization (with my api key) but, when I send request, I receive this error:
Invalid Content-Type header (application/json; boundary=------------------------66a0b850cd1421c8), expected application/json
I tried to use some of your options with no success.
I cannot remove the boundary parameter added automatically.
I've been stuck with this problem for a little while now. I am trying to use a REST API to change certain settings of a user like clear a user and set their device to inactive.
The REST calls are made in php which I am pretty new to. Most calls (get and post) are working just fine so I think I understood the basic concept of php and curl but I just can't get put requests working. The problem is that when making the REST call I get a status code 200 in return indicating that everything went fine but when I check the database nothing changed and the device is still active.
I've spent several hours researching this problem here on stackexchange (cURL PUT Request Not Working with PHP, Php Curl return 200 but not posting, PHP CURL PUT function not working) and additionally reading various tutorials.
To me my code looks fine and makes perfect sense because it is similar to many examples I found online. So please help me find my mistake.
$sn = "123456789";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com/api/sn/".$sn);
$data = array("cmd" => "clearUser");
$headers = array(
'Accept: application/json',
'Content-Type: application/json'
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$username = 'XXX';
$password = 'XXX';
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($data));
$output = curl_exec($ch);
curl_close($ch);
So far as I can see, you have two problems in your code.
Content-Type: application/json is incorrect, I would remove it entirely.
You don't have a Content-Length header.
I suggest trying
$sn = "123456789";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com/api/sn/".$sn);
$data = array("cmd" => "clearUser");
$httpQuery = http_build_query($data);
$headers = array(
'Accept: application/json',
'Content-Length: ' . strlen($httpQuery)
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$username = 'XXX';
$password = 'XXX';
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS,$httpQuery);
$output = curl_exec($ch);
curl_close($ch);
You define in the Header 'Content-Type: application/json'. Try to encode your $data to json and then transfer the jsonEncodeteData:
$dataJson = json_encode($data);
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataJson);
perhaps this helps already.
status 200 may not be a success in the case of a PUT request. In a correct semantics (correct implementation of the server) successful PUT returns "201 Created" and, if the client sends empty or somehow wrong content, the server returns "204 No Content".
Lazy programmers may just return "200 Ok" instead of 204 with the meaning "your request is fine, but there is nothing to do with the data".
Try to verify your data and make sure that you send something that is not empty and is conformal to the API specs.
I am trying to generate a token using OAuth 2.0
I redirect the user to the given URL,
User logs in, grants permission,
and then user is returned to my RETURN_URL
Below is the code for my RETURN_URL, and it gives following error:
{"code":400,"status":"Bad Request","timestamp":"2018-11-06T17:41:08+05:30","message":"Bad Request","error":{"reason":"Something wrong in request"}}
$code= $_GET[code];
$url = 'https://api.example.com/index/oauth/token';
$auth = $API_KEY.":".$API_SECRET ;
$header = array();
$header[] = 'Content-Type: application/json';
$header[] = 'x-api-key: '.$API_KEY;
$header[] = 'Authorization: Basic '. base64_encode($auth);
$data = array(
'code' => $code,
'grant_type' => 'authorization_code',
'redirect_uri' => $RETURN_URL
);
$data = trim(http_build_query($data));
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data );
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
//curl_setopt($ch, CURLOPT_USERPWD, $API_KEY.":".$API_SECRET );
//curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
//curl_setopt($curl, CURLOPT_USERPWD, "$API_KEY:$API_SECRET" );
curl_setopt($ch, CURLOPT_HEADER, 0);
$result= curl_exec($ch);
$error = curl_error($ch);
echo $result; exit;
curl_close($ch);
This is what their docs are saying for required parameters:
curl \
-u {your_api_key}:{your_api_secret} \
-H 'Content-Type: application/json' \
-H 'x-api-key: {your_api_key}' \
-d '{"code" : "{code_from_login_response}", "grant_type" : "authorization_code", "redirect_uri" : "{your_redirect_uri}"}' \
The reason you are getting a 400 bad request is because the API server that you are hitting is unable to understand the $data you sent and JSON decode it. Hence, below steps might help in sending a proper POST request with proper JSON-
Change $_GET[code] to $_GET['code']. It works without the single quotes but it does generate a notice of undefined constant 'code'. Also, you might want to filter this data for security reasons.
remove $data = trim(http_build_query($data));.
Change this line curl_setopt($ch, CURLOPT_POSTFIELDS, $data ); to curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data) ); and you should be good to go.
The reason why this might be happening as far as I see is because probably API Server you are hitting is receiving your JSON data as $json = file_get_contents('php://input');, kind of like a webhook. So, when you made a request, it wasn't able to parse your data as JSON and hence sent you a bad request error.
I am calling an API using CURL.
When I run it directly in browser or via ajax request it runs well and gives xml output.The Api am calling stores the xml in a database table and would only then work well.
However when I call it via PHP curl their table is not getting updated.
The code am doing it with PHP curl is
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$headers = array();
$headers[] = "Accept: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
Sample URL : http://example.com/code=x05a&businessKeyValue=8519ada0-9e2f-e265-8698-5b6145af9704&entity=funded_program_concession¶meters=fpc_funded_program_concession_id%7C8519ada0-9e2f-e265-8698-5b6145af9704¶meters=fps_funded_program_subsidy_id%7Cf320f2d9-7c6a-0b56-2940-5b61147a0f3d
If I open this link which opens it in browser, it works good, but if I run it via curl the API is not receiving xml content.
How can I resolve this issue?
$api='http://example.com/code=x05a&businessKeyValue=8519ada0-9e2f-e265-8698-5b6145af9704&entity=funded_program_concession¶meters=fpc_funded_program_concession_id%7C8519ada0-9e2f-e265-8698-5b6145af9704¶meters=fps_funded_program_subsidy_id%7Cf320f2d9-7c6a-0b56-2940-5b61147a0f3d';
$ch = curl_init();
$headers = array();//put your headers only if you need them
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result= curl_exec($ch);
return $result;
This should work for you. Inside your headers array make sure you put the headers you need and not extra. This is a simple curl, get call so i guess the above code will work without any trouble.
If you want to accept xml then you can got for Accept:application/xml or Accept:application/xhtml+xml
If the above methods don't work provide us with your error.
echo 'Curl error: ' . curl_error($ch);
Add the above line as a breaking point in your code and see what's the error.
I'm developing code for an estate agent to upload properties to Zoopla via their datafeed
I'm having problem adding a required profile to the http header that is required
The only example in the documentation is this test from linux:
echo '{ "branch_reference" : "test" }' |
curl --key /path/to/private.pem --cert /path/to/certificate.crt --data #-
--header "Content-type: application/json;
profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.1/schemas/listing/list.json"
https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list
I'm having a problem adding the profile to the http header in cURL
Here's my code:
$json['branch_reference']="test";
$json=json_encode($json);
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSLKEY,'private.pem');
curl_setopt($ch, CURLOPT_SSLCERT,'zpg_realtime_listings_1468337696150754_20160712-20260710.crt');
curl_setopt($ch, CURLOPT_URL, "https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'profile: http://realtime-listings.webservices.zpg.co.uk/docs/v1.1/schemas/listing/list.json'
));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
if(curl_error($ch)){echo "CURL ERROR ".curl_error($ch)."<br>";}
$result = curl_exec($ch);
curl_close($ch);
echo $result;
The response I'm getting from Zoopla is:
{ "error_advice" : "The Content-Type header is missing the 'profile' parameter. Please supply 'profile', specifying the schema URL for the method you are calling: /sandbox/v1/listing/list", "error_name" : "missing_profile" }
Can anbody please advise on the correct way to add the profile to the header?
Thanx
From their example, it looks like you should be passing the whole string as a single Content-Type HTTP header, rather than two separate ones:
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.1/schemas/listing/list.json'
);