POST using CURL in PHP gives invalid request Error - php

I am using below post method for google account using curl but it gives me invalid_request error.
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
code=4/ux5gNj-_mIu4DOD_gNZdjX9EtOFf&
client_id=1084945748469-eg34imk572gdhu83gj5p0an9fut6urp5.apps.googleusercontent.com&
client_secret=CENSORED&
redirect_uri=http://localhost/oauth2callback&
grant_type=authorization_code
Here is my PHP code with curl
$text ='test';
$URL = "https://accounts.google.com/o/oauth2/token";
$header = array(
"POST /o/oauth2/token HTTP/1.1",
"Host: accounts.google.com",
"Content-type: application/atom+xml;charset=\"utf-8\"",
"Accept: text/xml",
"Cache-Control: no-cache",
"code=[my_code]&client_id=[my_client_id]&client_secret=[my_client_secret]& redirect_uri=http://localhost/curl_resp.php&grant_type=authorization_code",
"Content-length: ".strlen($text),
);
$xml_do = curl_init();
curl_setopt($xml_do, CURLOPT_URL, $URL);
curl_setopt($xml_do, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($xml_do, CURLOPT_TIMEOUT, 10);
curl_setopt($xml_do, CURLOPT_RETURNTRANSFER, true);
curl_setopt($xml_do, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($xml_do, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($xml_do, CURLOPT_POST, false);
curl_setopt($xml_do, CURLOPT_POSTFIELDS, $text);
curl_setopt($xml_do, CURLOPT_HTTPHEADER, $header);
And I am having invalid request error

I don't know anything about using Google's oAuth API, but from the examples that I have looked at so far, it looks like you are supposed to pass the values (i.e. code, client_id, etc.) in the post fields, not directly in the HTTP header.
The following example still doesn't work completely, but instead of getting a invalid_request error, it gives you invalid_grant. I think there is something else wrong in addition to what I've mentioned (perhaps you need new credentials from Google or something), but this might get you one step closer, at least:
$post = array(
"grant_type" => "authorization_code",
"code" => "your_code",
"client_id" => "your_client_id",
"client_secret" => "your_client_secret",
"redirect_uri" => "http://localhost/curl_resp.php"
);
$postText = http_build_query($post);
$url = "https://accounts.google.com/o/oauth2/token";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postText);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$result = curl_exec($ch);
var_dump($result); // gets an error, "invalid_grant"

The response to your request actually includes a very readable description of the problem:
POST requests require a Content-length header.

Why do you have CURLOPT_POST set to false?
curl_setopt($xml_do, CURLOPT_POST, false);
Although some configurations of cURL will automatically change this to tru if CURLOPT_POSTFIELDS is set, you do not have a valid postfield.
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&para2=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.
It should either be in param=value syntax or an array passed.

I have used post array in CURL method and valid Google code and it worked for me

I was also having the same problem, where google returns an "invalid_xxx".
After much researching and troubleshooting, the problem lies with the encoding of the form itself! Do not use function 'http_builder_query', as it messses up the string and google cannot 'recognise' it. Example :
http_builder_query Output : "code=4%252FYYUT71KJ6..."
compared to
just a normal string : "code=4/YYUT71KJ6..."
Here is my working code, where i have placed 'x' in the locations that needs your own data (taken and modified from google oauth authentication)
$code_from_user_login = "4/YYUT71KJ6....";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://accounts.google.com/o/oauth2/token");
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$post_params = "code=" . $code_from_user_login . "&";
$post_params .= "redirect_uri=http://www.x.com/&";
$post_params .= "client_id=x.apps.googleusercontent.com&";
$post_params .= "client_secret=x&";
$post_params .= "grant_type=authorization_code&";
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_params);
$result = curl_exec($ch);
print($result);
The result will be like :
'{
"access_token" : "ya29.AHES6ZSwJSHpTZ1t....",
"token_type" : "Bearer",
"expires_in" : 3599,
"id_token" : "eyJhbGciOiJSUzI1NiIsImtpZCI6IjU0MDQxOTZlMmQzOGNjYTA2MW...."
}'
Once you have the 'access_token', access the profile data with this url :
https://www.googleapis.com/oauth2/v1/userinfo?access_token=YOUR_ACCESS_TOKEN_HERE
~ end ~

Related

i need to know how to call curl with api key parameter with given command

i have curl command provided by some developer, i need to know how to call it in php.
Command is :
curl -H "x-api-key: xxxxxxxxxxxxxxxxxxxxxx"
"https://api.civicengine.com/office-
holders?address=1060+W+Addison+Chicago+IL"
i have written this
$data['api-key']='xxxxxxxxxxxxxxxxxxxxx';
/*$data['host']='https://api.civicengine.com';*/
$url='https://api.civicengine.com/office-holders?address=1060+W+Addison+Chicago+IL';
$ch = curl_init();
// set basic auth
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
// set header accept
$headers = array('Accept:application/json', 'Accept-Language:en_US',"Authorization: Bearear xxxxxxxxxxxxxxxxxxxx");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// set mode to POST
curl_setopt($ch, CURLOPT_POST, 1);
// add post fields (1)
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL, $url);
// Execute
print_r($result = json_decode(curl_exec($ch)));die;
i expect result but its giving
stdClass Object ( [message] => Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header. Authorization=FLUdjGvxuJ9liutivB0Ll5LW2t2xmv31lvK2guQi )
you forgot to add the x-api-key header to your php curl_ code. also your php code is altering the Accept Accept-Language, and Authorization header, your curl invocation proves that's not needed, and they may be incorrect to boot (idk), get rid of them while debugging (and once everything is working, you may add them back and check that they don't break anything..)
Follow this method to send api_key in header of API REQUEST
// Collection object
$ch = curl_init($url);
$headers = array(
"APIKEY: PUT_HERE_API_KEY",
"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml"
);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlreq);
$result = curl_exec($ch); // execute
$result;
//show response
curl_close($ch);

im getting Error response as 405 Method Not Allowed

I'm getting Error response as 405 Method Not Allowed while trying with PHP CURl Please find my below Code and help me I'm critical condition
<?php
$credentials = "xxxx:yyyyy";
$a=base64_encode($credentials);
$url = "http://api.trust.in/get/token";
$page = "/get/token";
$headers = array(
"POST ".$page." HTTP/1.1",
"Content-Type: text/plain;charset=utf-8",
"Content-Length:0",
"Authorization: Basic " . base64_encode($credentials),
"Connection:keep-Alive",
"Host:xyz.abc.in"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL,$url);
$data = curl_exec($ch);
print_r(get_headers($url));
?>
do not set you header content-length become zero, should give length of parameter that you post to site, to test it you can use postman. it easier to know what you doing wrong using that.
Based on the documentation you provided, the url used for the API endpoint is not correct.
Instead of:
http://api.trust.in/get/token
Use:
http://api.toyotautrust.in/get/token
Please try that and give us the results.
Added empty array $params because of zero parameters for POST Request according to my document
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));

Setting a path HTTP GET Request using curl on PHP, for web API

I'm working on a web_app using teamviewer API. According to the documentation, it works using HTTP requests (GET, POST, etc..).
I don't get how to make a request on PHP using CURL. The documentation said to do this:
POST /api/v1/oauth2/token HTTP/1.1
Host: webapi.teamviewer.com
Content-Type: application/x-www-form-urlencoded
so I wrote this
$url = 'webapi.teamviewer.com';
$headers = array(
'GET /api/v1/oauth2/authorize HTTP/1.1',
'Content-type: application/x-www-form-urlencoded'
);
//data
$data = [
'response_type' => 'authorization_code',
'redirect_uri' => 'https%3A%2F%2FTesting%2Ecom%2F',
'client_id' => '65671-XDdsxUNyxGmskcJHQgLC'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
I just can't figure out how to indicate the request the HTTP/1.1 and the path /api/v1/oauth2/authorize. I'm putting it in the header but I'm sure it doesn't go there.
I use to work on embedded C and I remember that first you connect to the host and then write GET path HTTP/1.1 as a command.
Your $url should be the full path, just like a normal URL. So it would be
$url = 'webapi.teamviewer.com/api/v1/oauth2/authorize';
And you can remove the GET ... part from $headers, because the URL (path) doesn't go in there.
That should work after that. If you want to see more info about the curl connection and what's going on, add this option:
curl_setopt($ch, CURLOPT_VERBOSE, true);
The full list of curl options is at the PHP manual page on curl_setopt.

Trouble setting API key in POST request

trying to make an API request via curl. The API docs say I must make a POST request as follows:
POST url
Headers:
Content-Type: “application/json”
Body:
{
Context: {
ServiceAccountContext: "[Authorization Token]"
},
Request:{
Citations:[
{
Volume: int,
Reporter: str,
Page: int
}
]
}
}
Here is my curl request:
$postFields = array(
'Volume' => int,
'Reporter' => str,
'Page' => int,
'ServiceAccountContext' => $API_KEY
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type:application/json"));
curl_setopt($ch, CURLOPT_POST, count($postFields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
$output=curl_exec($ch);
But the API is not recognizing that I have submitted the API_KEY through a POST Field. The error I am getting back is to create a SecurityContext object, which I assume is something to do with the part of the POST body talking about Context and ServiceAccountContext.
I have looked in the cURL documentation and have not seen how I can set this. Any suggestions? Thanks a bunch.
The problem is that you use CURL options improperly. According to manual, when you set CURLOPT_POSTFIELDS option to an array, CURL forces Content-Type header to multipart/form-data. i.e. the line where you set CURLOPT_HTTPHEADER option is ignored.
You have to convert $postFields to JSON string by json_encode function before passing it to CURLOPT_POSTFIELDS option:
...
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type:application/json"));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postFields));
...

Google Closure Compiler and multipart/form-data not working

I'm making a request to the google closure compiler API service:
$content = file_get_contents('file.js');
$url = 'http://closure-compiler.appspot.com/compile';
$post = true;
$postData = array('output_info' => 'compiled_code', 'output_format' => 'text', 'compilation_level' => 'SIMPLE_OPTIMIZATIONS', 'js_code' => urlencode($content)));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if ($post) {
curl_setopt($ch, CURLOPT_POST, $post);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded; charset=UTF-8'));
But the request is failing and I get this error message from google:
Error(18): Unknown parameter in Http request: '------------------------------0f1f2f05fb97
Content-Disposition: form-data; name'.
Error(13): No output information to produce, yet compilation was requested.
I looked at the headers and this Content-Type header is being sent:
application/x-www-form-urlencoded; charset=UTF-8; boundary=----------------------------0f1f2f05fb97
Not sure if that added boundary is normal? And how do I prevent this as google doesn't seem to like it?
Thank you,
Wesley
You have to use http_build_query() prior to sending POST data (array) to cURL.
string http_build_query ( mixed $query_data [, string $numeric_prefix [, string $arg_separator [, int $enc_type = PHP_QUERY_RFC1738 ]]] )
So your $postData should look like this:
$postData = http_build_query(
array(
'output_info' => 'compiled_code',
'output_format' => 'text',
'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
'js_code' => urlencode($content)
)
);
Looks like Google's API doesn't support multipart/form-data data. Which seems a bit lame to me...
According to the PHP documentation on curl_setopt():
Passing an array to CURLOPT_POSTFIELDS will encode the data as multipart/form-data,
while passing a URL-encoded string will encode the data as application/x-www-form-urlencoded.
So it should work if you change the 4th line of your code to something like this:
$postData = 'output_info=compiled_code&output_format=text&compilation_level=SIMPLE_OPTIMIZATIONS&js_code=' . urlencode($content);
In other words, you have to do the URL encoding yourself - you apparently can't rely on cURL to take an array and encode it for you.
1.) Don't use an array() to avoid switch to multipart/form-data:
Passing an array to CURLOPT_POSTFIELDS will encode the data as
multipart/form-data, while passing a URL-encoded string will encode
the data as application/x-www-form-urlencoded.
2.) Don't use http_build_query() to avoid double encoding problems (#Wesley). In addition you aren't able to use keys twice (I know this workaround, but its ugly).
Some of my error messages by using http_build_query():
JSC_PARSE_ERROR Input_0
Parse error. illegal octal literal digit 9; interpreting it as a decimal digit
Parse error. syntax error
ERROR - Parse error. missing ( before function parameters
3.) My proposal:
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Expect:',
'Content-type: application/x-www-form-urlencoded',
));
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // don't set it to low! sending and response needs time
curl_setopt($ch, CURLOPT_ENCODING, ''); // automatically sets supported encodings
//curl_setopt($ch, CURLOPT_HEADER, true); // for debugging response header
//curl_setopt($ch, CURLINFO_HEADER_OUT, true); // for debugging request header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // false would echo the answer
curl_setopt($ch, CURLOPT_POST, true);
// settings
curl_setopt($ch, CURLOPT_POSTFIELDS,
'output_format=json'
.'&output_info=compiled_code'
.'&output_info=warnings'
.'&output_info=errors'
.'&output_info=statistics'
.'&compilation_level=ADVANCED_OPTIMIZATIONS'
.'&warning_level=verbose'
//.'&output_file_name=default.js'
//.'&code_url='
.'&js_code=' . urlencode($js_code)
);
curl_setopt($ch, CURLOPT_URL, 'http://closure-compiler.appspot.com/compile');
$response = curl_exec($ch);
//$response = curl_getinfo($ch, CURLINFO_HEADER_OUT) . $response; // for debugging request header
print_r(json_decode($response, true));

Categories