PHP。如何获取访问令牌。使用 Google API 的 OAuth 2.0 进行身份验证

发布于 2024-12-27 07:56:15 字数 1691 浏览 2 评论 0原文

我发现这个函数据说可以获取accessToken,但我什么也没得到。 我确实有 $_REQUEST['code'] 以及该函数所需的其他信息。

任何想法这里有什么问题吗? 谢谢。

//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;
}

I found this function that supposedly gets the accessToken, but I get nothing.
I do have the $_REQUEST['code'], and the other information needed in this function.

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

红颜悴 2025-01-03 07:56:15

这就是我为获取访问令牌和刷新令牌所做的事情。

创建一个包含以下代码的文件:

<?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);
}

现在,将 YOUR_CLIENT_IDYOUR_CLIENT_SECRET 替换为您的客户端 ID 和客户端密钥。

确保您的范围正确。例如,如果您想访问 Analytics,则应为 https://www.googleapis.com/auth/analytics

如果运行该文件,您应该会看到 OAuth2 批准屏幕。

如果您现在按接受,您应该会得到如下所示的结果:

{
  "access_token" : YOUR_ACCESS_TOKEN,
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "refresh_token" : YOUR_REFRESH_TOKEN
}

该结果可能包含其他字段,具体取决于您申请的范围。

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.

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.

If you run the file, you should get an OAuth2 approval screen.

If you now press Accept, you should get a result that looks like this:

{
  "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.

你的他你的她 2025-01-03 07:56:15

我没有发现您的代码有任何问题,但您可能想尝试刷新客户端密钥,看看是否有帮助。另外,我建议您准确查看curl命令返回的响应,我怀疑它是“invalid_grant”。

更好的方法是使用 google 的 php api 客户端:

https:// /code.google.com/p/google-api-php-client/

它为您处理大部分通信。那里的例子非常容易使用。这主要取决于您尝试访问哪个谷歌服务。

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".

A much better way to do this is to use google's php api 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.

贪了杯 2025-01-03 07:56:15

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

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

    回显$json_response;

  2. 获取 Fiddler 并在调用curl_exec之前使用以下行

    curl_setopt($curl, CURLOPT_PROXY, '127.0.0.1:8888');

'恐怕我也没有让它工作 - 我得到的回应是

{ 
     "error" : "invalid_request" 
}

现在如果有人知道这是怎么回事;)

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

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

感受沵的脚步 2025-01-03 07:56:15

来自“OAuth 2.0 授权协议草案-ietf-oauth-v2-20”的第 4.4.2 节

客户端通过添加以下内容向令牌端点发出请求
使用“application/x-www-form-urlencoded”的以下参数
HTTP请求实体主体中的格式:

所以POSTed参数应该以字符串的形式提交,而不是数组。 PHP 手册中的curl_setopt 也提到了这一点。

因此,您可能不想发布 $clienttoken_post,而是发布 http_build_query($clienttoken_post,'','&')。

这可能无法解决您的所有问题,但这可能是朝着正确方向迈出的一步。

From section 4.4.2 of "The OAuth 2.0 Authorization Protocol draft-ietf-oauth-v2-20"

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:

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.

So instead of posting $clienttoken_post, you might want to post http_build_query($clienttoken_post,'','&').

This might not solve all your problems, but it's probably a step in the right direction.

相权↑美人 2025-01-03 07:56:15

我遇到了同样的错误,我发现添加

curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);

允许请求遵循重定向很快就解决了它。我希望这对其他人有帮助!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文