php - 谷歌 API 客户端 "refresh token must be passed in or set as part of setAccessToken"

标签 php google-api google-calendar-api access-token google-api-php-client

我目前面临一个非常奇怪的问题,实际上我一直在遵循来自 Google API 文档的指南 ( https://developers.google.com/google-apps/calendar/quickstart/php )。我尝试了两次,第一次它工作得很好,但在访问 token 过期后,Google API Doc 直接提供的脚本无法刷新它。

长话短说

这是错误信息:

sam@ssh:~$ php www/path/to/app/public/quickstart.php


Fatal error: Uncaught exception 'LogicException' with message 'refresh token must be passed in or set as part of setAccessToken' in /home/pueblo/www/path/to/app/vendor/google/apiclient/src/Google/Client.php:258
Stack trace:
#0 /home/pueblo/www/path/to/app/public/quickstart.php(55): Google_Client->fetchAccessTokenWithRefreshToken(NULL)
#1 /home/pueblo/www/path/to/app/public/quickstart.php(76): getClient()
#2 {main}
  thrown in /home/pueblo/www/path/to/app/vendor/google/apiclient/src/Google/Client.php on line 258

这是我修改过的来自 google 的 php 脚本的一部分:

require_once __DIR__ . '/../vendor/autoload.php';

// I don't want the creds to be in my home folder, I prefer them in the app's root
define('APPLICATION_NAME', 'LRS API Calendar');
define('CREDENTIALS_PATH', __DIR__ . '/../.credentials/calendar-php-quickstart.json');
define('CLIENT_SECRET_PATH', __DIR__ . '/../client_secret.json');

我还修改了 expandHomeDirectory,这样我就可以在不修改太多代码的情况下“禁用”它:

function expandHomeDirectory($path) {
  $homeDirectory = getenv('HOME');
  if (empty($homeDirectory)) {
    $homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
  }
  return $path;
  // return str_replace('~', realpath($homeDirectory), $path);
}

所以为了检查是我错了还是 Google 错了,我做了一个实验:昨天晚上我从 ssh 启动快速启动脚本来检查它是否工作,确实如此,所以我决定今天早上检查它是否仍然像我 sleep 前一样工作,但事实并非如此,所以我认为 Google 的 quickstart.php 有问题。

我希望有人能帮助我,我已经检查了所有关于这个主题的其他帖子,但它们都已经过时了。

最佳答案

我最近遇到了同样的问题,我用这个解决了。

<?php
 $client->setRedirectUri($this->_redirectURI);
 $client->setAccessType('offline');
 $client->setApprovalPrompt('force');

我解释一下...... 没有返回刷新 token ,因为我们没有强制执行批准提示。离线模式是不够的。我们必须强制批准提示。此外,必须在这两个选项之前设置 redirectURI。它对我有用。

这是我的全部功能

<?php
     private function getClient()
     {
        $client = new Google_Client();
        $client->setApplicationName($this->projectName);
        $client->setScopes(SCOPES);
        $client->setAuthConfig($this->jsonKeyFilePath);
        $client->setRedirectUri($this->redirectUri);
        $client->setAccessType('offline');
        $client->setApprovalPrompt('force');

       // Load previously authorized credentials from a file.
       if (file_exists($this->tokenFile)) {
         $accessToken = json_decode(file_get_contents($this->tokenFile), 
         true);
      } else {
        // Request authorization from the user.
        $authUrl = $client->createAuthUrl();
        header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));

        if (isset($_GET['code'])) {
            $authCode = $_GET['code'];
            // Exchange authorization code for an access token.
            $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
            header('Location: ' . filter_var($this->redirectUri, 
            FILTER_SANITIZE_URL));
            if(!file_exists(dirname($this->tokenFile))) {
                mkdir(dirname($this->tokenFile), 0700, true);
            }

            file_put_contents($this->tokenFile, json_encode($accessToken));
        }else{
            exit('No code found');
        }
    }
    $client->setAccessToken($accessToken);

    // Refresh the token if it's expired.
    if ($client->isAccessTokenExpired()) {

        // save refresh token to some variable
        $refreshTokenSaved = $client->getRefreshToken();

        // update access token
        $client->fetchAccessTokenWithRefreshToken($refreshTokenSaved);

        // pass access token to some variable
        $accessTokenUpdated = $client->getAccessToken();

        // append refresh token
        $accessTokenUpdated['refresh_token'] = $refreshTokenSaved;

        //Set the new acces token
        $accessToken = $refreshTokenSaved;
        $client->setAccessToken($accessToken);

        // save to file
        file_put_contents($this->tokenFile, 
       json_encode($accessTokenUpdated));
    }
    return $client;
}

关于php - 谷歌 API 客户端 "refresh token must be passed in or set as part of setAccessToken",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39314833/

相关文章:

php - 使用 PHP 在 SQL 查询中指定时间

google-api - googleapi_auth,它如何真正工作?

python - Youtube API 获取当前搜索词?

javascript - 使用 Javascript API 登录谷歌而不触发弹出窗口

api - Google 日历 API 和 Coldfusion

php - 使用列表作为选择内部表单

php - 如何将多个可重复字段保存为数据库中的数组?

php - Mysql从两个具有相同结构的不同表中选择

excel - 使用 Excel 2007 VBA 将事件添加到 Google 日历

java - Google 日历 API Java 403