问题
with this simple code I manage to get Google's access tokens. See the code:
public function authenticate($code = null) {
if (!$code) {
if ($this->log)
error_log(__CLASS__ . '::authenticate() error: $code is null.');
return false;
}
$client_id = $this->token->get('client_id');
$client_secret = $this->token->get('client_secret');
$redirect_uri = $this->token->get('redirect_uri');
$url = $this->token->get('token_endpoint');
$curlPost = 'client_id=' . $client_id . '&client_secret=' . $client_secret . '&redirect_uri=' . $redirect_uri . '&code='. $code . '&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$buffer = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = \json_decode($buffer, true);
if ($http_code != 200) {
$log = __CLASS__ . '::authenticate() error: http code not 200. Responded: '.print_r($data, true);
$return = false;
} else {
$this->auth = $data;
$return = true;
$log = __CLASS__ . '::authenticate() returns '.$return.' and sets this->auth='.print_r($data, true);
}
if ($this->log)
error_log($log);
return $return;
}
you can see my project there with a test file.
My question is about the verify()
function.
When I want to verify Google's access token by typing in the browser sth like https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=....
I get immediately a response from Google but when I try the following function with cURL it fails miserably:
public function verify($access_token = null) {
if (!$access_token) {
if ($this->log)
error_log(__CLASS__ . '::verify() error: $access_token is null.');
return false;
}
$url = $this->token->get('verify_endpoint');
$curlPost = 'access_token='. $access_token;
//$curlPost = \http_build_query(array('access_token' => $access_token));
//$curlPost = array('access_token' => $access_token);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url.'?'.$curlPost);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
//curl_setopt($ch, CURLOPT_VERBOSE, true);
$buffer = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = \json_decode($buffer, true);
if ($http_code != 200) {
$log = __CLASS__ . '::verify() error: http code not 200. Responded: '.print_r($data, true);
$return = false;
} else {
$this->verify = $data;
$log = __CLASS__ . '::verify() sets this->verify='.print_r($data, true);
$return = true;
}
if ($this->log)
error_log($log);
return $return;
}
Has this sth to do with cURL? Any answer is welcomed.
Just to clarify: browser request https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=...
or with ?id_token=...
always succeeds BUT not cURL with the proper tokens in the query part of course.
回答1:
From your source code here
$this->set('verify_endpoint', 'https://www.googleapis.com/oauth2/v2/tokeninfo');
is calling googles token info end point documentation is used for validating an id token you appear to be passing it an access token. This is not going to work.
TBH i dont understand why you would bother validating an access token. The best way to test if an access token is working is to make the call to the API in question if it doesnt work you will get an error back. Why would you want to make a call to test if it works then use it if it does work your doubling your requests.
回答2:
Problems solved!
After a 2 month searching at last there is an update version of my project wirh cUrl
problems solved immediately after started to investigate errors sent by the curl environment.
The browser success ringed a bell that probably there was a DNS
issue as these threads repeatedly showcase this:
- https://curl.haxx.se/mail/curlphp-2016-10/0000.html
- https://forums.rancher.com/t/dns-caching-issues/1566/8 @vincent
- https://github.com/GoogleCloudPlatform/google-cloud-php/issues/405
- https://github.com/google/google-api-php-client/issues/1184
This discussion from @sanmai
about CURLOPT_RESOLVE
actually made it working! Also see php manual; The same is proposed here by Luc van Donkersgoed and there by John Hart.
The tricky parts of response headers on GET
requests that contain Google's response are discussed here and in other places.
Curl certificates are downloaded from there. A discussion for certificates is there.
A discussion for debugging cUrl
here and there.
For a discussion of Expect
header and it's implications you can read this and that.
Now cUrl
is lightning fast when it connects to google. See my project.
My deepest gratitude to all the users who patiently and kindly support the community. You guys are awesome! many thanks!
来源:https://stackoverflow.com/questions/47940730/why-curls-fails-to-verify-google-access-token-whereas-browser-succeeds