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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 05:45:37  来源:igfitidea点击:

PHP. How to get the access token. Authenticating with OAuth 2.0 for Google API

phpoauth-2.0access-token

提问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_IDand YOUR_CLIENT_SECRETwith your client ID and client secret.

现在,用您的客户端 ID 和客户端密钥替换YOUR_CLIENT_IDYOUR_CLIENT_SECRET

Make sure your scope is correct. For example, it should be https://www.googleapis.com/auth/analyticsif 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.

该代码看起来很熟悉-我使用的代码大致相同-您可以尝试两件事。

  1. Use echo to echo the response to the Browser

    echo $json_response;

  2. 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');

  1. 使用 echo 将响应回显到浏览器

    回声 $json_response;

  2. 获取 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!

允许请求跟随重定向快速解决它。我希望能帮助别人!