PHP。如何获取访问令牌。使用 OAuth 2.0 for Google API 进行身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8902376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP. How to get the access token. Authenticating with OAuth 2.0 for Google API
提问by Patrioticcow
I found this functionthat supposedly gets the accessToken, but I get nothing.
I do have the $_REQUEST['code']
, and the other information needed in this function.
我发现这个函数可以获取 accessToken,但我什么也没得到。我确实有$_REQUEST['code']
,以及此功能所需的其他信息。
Any ideas what is wrong here? Thanks.
任何想法这里有什么问题?谢谢。
//Oauth 2.0: exchange token for session token so multiple calls can be made to api
if(isset($_REQUEST['code'])){
$_SESSION['accessToken'] = get_oauth2_token($_REQUEST['code']);
}
//returns session token for calls to API using oauth 2.0
function get_oauth2_token($code) {
global $client_id;
global $client_secret;
global $redirect_uri;
$oauth2token_url = "https://accounts.google.com/o/oauth2/token";
$clienttoken_post = array(
"code" => $code,
"client_id" => $client_id,
"client_secret" => $client_secret,
"redirect_uri" => $redirect_uri,
"grant_type" => "authorization_code"
);
$curl = curl_init($oauth2token_url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $clienttoken_post);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$json_response = curl_exec($curl);
curl_close($curl);
$authObj = json_decode($json_response);
if (isset($authObj->refresh_token)){
//refresh token only granted on first authorization for offline access
//save to db for future use (db saving not included in example)
global $refreshToken;
$refreshToken = $authObj->refresh_token;
}
$accessToken = $authObj->access_token;
return $accessToken;
}
采纳答案by groffhibbitz
I don't see anything wrong with your code, but you may want to try refreshing the client secret and see if that helps. Additionally, I would suggest you see exactly what the response is coming back from your curl command, I suspect it's "invalid_grant".
我看不出你的代码有什么问题,但你可能想尝试刷新客户端密码,看看是否有帮助。此外,我建议您准确查看 curl 命令返回的响应,我怀疑它是“invalid_grant”。
A much better way to do this is to use google's php api client:
一个更好的方法是使用谷歌的 php api 客户端:
https://code.google.com/p/google-api-php-client/
https://code.google.com/p/google-api-php-client/
which handles most of the communication for you. The examples there are very easy to use. It mostly depends on which google service you are trying to access.
它为您处理大部分通信。那里的示例非常易于使用。这主要取决于您尝试访问的 Google 服务。
回答by John Slegers
This is what I did to get my access token and refresh token.
这就是我为获取访问令牌和刷新令牌所做的工作。
Create a file that contains the following code :
创建一个包含以下代码的文件:
<?php
if (isset($_GET['code'])) {
// try to get an access token
$code = $_GET['code'];
$url = 'https://accounts.google.com/o/oauth2/token';
$params = array(
"code" => $code,
"client_id" => YOUR_CLIENT_ID,
"client_secret" => YOUR_CLIENT_SECRET,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"grant_type" => "authorization_code"
);
$ch = curl_init();
curl_setopt($ch, constant("CURLOPT_" . 'URL'), $url);
curl_setopt($ch, constant("CURLOPT_" . 'POST'), true);
curl_setopt($ch, constant("CURLOPT_" . 'POSTFIELDS'), $params);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] === 200) {
header('Content-Type: ' . $info['content_type']);
return $output;
} else {
return 'An error happened';
}
} else {
$url = "https://accounts.google.com/o/oauth2/auth";
$params = array(
"response_type" => "code",
"client_id" => YOUR_CLIENT_ID,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"scope" => "https://www.googleapis.com/auth/plus.me"
);
$request_to = $url . '?' . http_build_query($params);
header("Location: " . $request_to);
}
Now, replace YOUR_CLIENT_ID
and YOUR_CLIENT_SECRET
with your client ID and client secret.
现在,用您的客户端 ID 和客户端密钥替换YOUR_CLIENT_ID
和YOUR_CLIENT_SECRET
。
Make sure your scope is correct. For example, it should be https://www.googleapis.com/auth/analytics
if you want to get access to Analytics.
确保您的范围是正确的。例如,https://www.googleapis.com/auth/analytics
如果您想访问 Analytics ,就应该这样做。
If you run the file, you should get an OAuth2 approval screen.
如果您运行该文件,您应该会看到一个 OAuth2 批准屏幕。
If you now press Accept
, you should get a result that looks like this:
如果现在按Accept
,您应该得到如下所示的结果:
{
"access_token" : YOUR_ACCESS_TOKEN,
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : YOUR_REFRESH_TOKEN
}
The result may contain additional fields, depending on which scope you're applying for.
结果可能包含其他字段,具体取决于您申请的范围。
回答by Paul S Chapman
that code looks familiar - I'm using roughly the same code - there are two things you can try.
该代码看起来很熟悉-我使用的代码大致相同-您可以尝试两件事。
Use echo to echo the response to the Browser
echo $json_response;
Get hold of Fiddler and use the following line before the call to curl_exec
curl_setopt($curl, CURLOPT_PROXY, '127.0.0.1:8888');
使用 echo 将响应回显到浏览器
回声 $json_response;
获取 Fiddler 并在调用 curl_exec 之前使用以下行
curl_setopt($curl, CURLOPT_PROXY, '127.0.0.1:8888');
'fraid I've not got it working either - the response I am getting is
'恐怕我也没有让它工作 - 我得到的回应是
{
"error" : "invalid_request"
}
Now if anyone knows how what is wrong with this ;)
现在,如果有人知道这有什么问题的话;)
回答by user2883217
From section 4.4.2 of "The OAuth 2.0 Authorization Protocol draft-ietf-oauth-v2-20"
来自“OAuth 2.0 授权协议草案-ietf-oauth-v2-20”的第 4.4.2 节
The client makes a request to the token endpoint by adding the following parameters using the "application/x-www-form-urlencoded" format in the HTTP request entity-body:
客户端通过在 HTTP 请求实体正文中使用“application/x-www-form-urlencoded”格式添加以下参数来向令牌端点发出请求:
So the POSTed parameters should be submitted in the form of a string, not an array. This is mentioned in the PHP manual for curl_setopt too.
所以 POSTed 参数应该以字符串的形式提交,而不是数组。这在 curl_setopt 的 PHP 手册中也有提到。
So instead of posting $clienttoken_post, you might want to post http_build_query($clienttoken_post,'','&').
因此,您可能希望发布 http_build_query($clienttoken_post,'','&'),而不是发布 $clienttoken_post。
This might not solve all your problems, but it's probably a step in the right direction.
这可能无法解决您的所有问题,但可能是朝着正确方向迈出的一步。
回答by Fred
I had the same error, and I found that adding
我有同样的错误,我发现添加
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
to allow the request follow a redirect solved it quickly. I hope that helps someone else!
允许请求跟随重定向快速解决它。我希望能帮助别人!