可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
回答1:
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"
回答2:
The response to your request actually includes a very readable description of the problem:
POST requests require a Content-length
header.
回答3:
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¶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.
It should either be in param=value syntax or an array passed.
回答4:
I have used post array in CURL method and valid Google code and it worked for me
回答5:
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 ~