Google API致命错误:未捕获LogicException:刷新令牌必须传入或设置为setAccessToken的一部分 [英] Google API Fatal error: Uncaught LogicException: refresh token must be passed in or set as part of setAccessToken

查看:157
本文介绍了Google API致命错误:未捕获LogicException:刷新令牌必须传入或设置为setAccessToken的一部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 PHP快速入门代码,我发现了一个问题:何时令牌需要刷新,代码返回以下错误:

Working with the PHP Quickstart code, I found a problem: when the token needs to be refreshed, the code returns the following error:


致命错误:未捕获LogicException:刷新令牌必须在$ b中传递$ b或作为setAccessToken的一部分设置在
/app/vendor/google/apiclient/src/Google/Client.php:258

Fatal error: Uncaught LogicException: refresh token must be passed in or set as part of setAccessToken in /app/vendor/google/apiclient/src/Google/Client.php:258

堆栈跟踪中:

#0 /app/gmail.php(32):
Google_Client-> fetchAccessTokenWithRefreshToken(NULL)

#0 /app/gmail.php(32): Google_Client->fetchAccessTokenWithRefreshToken(NULL)

#1 /app/test.php(14):getClient()

#1 /app/test.php(14): getClient()

#2 {main}抛出
/ app / vendor / google /第258行上的apiclient / src / Google / Client.php

#2 {main} thrown in /app/vendor/google/apiclient/src/Google/Client.php on line 258

我修改了 getClient()函数如下:

function getClient() {
    $client = new Google_Client();
    $client->setApplicationName(APPLICATION_NAME);
    $client->setScopes(SCOPES);
    $client->setAuthConfig(CLIENT_SECRET_PATH);
    $client->setRedirectUri(REDIRECT_URL);
    $client->setAccessType('offline');
    $client->setApprovalPrompt('force');

    // Load previously authorized credentials from a file.
    $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);

    if (file_exists($credentialsPath)) {
        $accessToken = json_decode(file_get_contents($credentialsPath), true);
    } 
    else {
        // Request authorization from the user.
        $authUrl = $client->createAuthUrl();
        return printf("<a href='%s' target='_blank'>auth</a><br />", $authUrl);
    }
    $client->setAccessToken($accessToken);

    // Refresh the token if it's expired.
    // ERROR HERE !!
    if ($client->isAccessTokenExpired()) {
        $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
        file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
    }
    return $client;
}

首次验证后(使用在 getClient()函数),当用户登陆到 REDIRECT_URL 时,会出现 callbackAuth()执行函数:

After the first authentication (using the link created in the getClient() function), when the user lands to REDIRECT_URL, a callbackAuth() function is executed:

function callbackAuth() {
    $client = new Google_Client();
    $client->setApplicationName(APPLICATION_NAME);
    $client->setScopes(SCOPES);
    $client->setAuthConfig(CLIENT_SECRET_PATH);
    $client->setRedirectUri(REDIRECT_URL);
    $client->setAccessType('offline');
    $client->setApprovalPrompt('force');

    // Load previously authorized credentials from a file.
    $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);

    // Request authorization from the user.
    $authCode = trim($_GET['code']);

    // Exchange authorization code for an access token.
    $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);

    // Store the credentials to disk.
    if(!file_exists(dirname($credentialsPath))) {
      mkdir(dirname($credentialsPath), 0700, true);
    }
    file_put_contents($credentialsPath, json_encode($accessToken));
    printf("Credentials saved to %s\n", $credentialsPath);

    $client->setAccessToken($accessToken);

    return $client;
}

我尝试应用其他相关\">stackoverflow问题,但没有结果。为什么会发生此错误?

I tried to apply the solutions of other related stackoverflow question, but without results. Why does this error ocurr?

推荐答案

感谢 Alex Blex 我注意到我第一次收到令牌时有 refresh_token ,但是在第一个请求之后, refresh_token 未存储。解决方案如下(来自此答案):

Thanks to Alex Blex I was able to notice that the first time I receive the token has the refresh_token but after the first request, the refresh_token is not stored. The solution is the following (from this answer):

// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
    $newAccessToken = $client->getAccessToken();
    $accessToken = array_merge($accessToken, $newAccessToken);
    file_put_contents($credentialsPath, json_encode($accessToken));
}




refresh_token仅在第一次请求时返回。当您
第二次刷新访问令牌时,它将返回除
以外的所有内容,refresh_token和file_put_contents会在第二次发生此操作时删除refresh_token

The refresh_token is only returned on the first request. When you refresh the access token a second time it returns everything except the refresh_token and the file_put_contents removes the refresh_token when this happens the second time.

按如下所示修改代码,会将原始访问
令牌与新令牌合并。这样,您将能够
保留您的refresh_token以供将来使用。

Modifying the code as following will merge in the original access token with the new one. This way you will be able to preserve your refresh_token for future requests.

这篇关于Google API致命错误:未捕获LogicException:刷新令牌必须传入或设置为setAccessToken的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆