为什么curls无法验证google访问令牌,而浏览器成功? [英] Why curls fails to verify google access token whereas browser succeeds?
问题描述
通过这个简单的代码,我设法获得了Google的访问令牌. 参见代码:
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;
}
您可以看到我的项目有一个测试文件.
我的问题是关于verify()
函数的.
当我想通过输入诸如https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=....
之类的浏览器来验证Google的访问令牌时,我会立即收到Google的回复,但是当我尝试使用cURL进行以下功能时,它会失败:
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;
}
这与cURL有关吗?欢迎任何答案.
只需澄清一下:浏览器请求https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=...
或与?id_token=...
一起总是成功,但是在查询部分中使用 proper 标记不是cURL .
问题已解决!
经过2个月的搜索,我的项目有了一个更新版本.cUrl
开始研究curl环境发送的错误后,问题立即得到解决.
浏览器的成功敲响了警钟,可能是一个DNS
问题,因为这些线程反复展示了这一点:
- 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
这来自关于CURLOPT_RESOLVE
的@sanmai
实际上使它起作用了!另请参见 php手册; Luc van在此处提出了相同的建议Donkersgoed和John Hart的有.
现在cUrl
连接到Google时闪电般快速.参见我的项目.
我对所有耐心和热情支持社区的用户表示最深切的感谢.你们真棒!非常感谢!
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.
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!
这篇关于为什么curls无法验证google访问令牌,而浏览器成功?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!