Intereting Posts
Использование переменной в качестве оператора создание изображения в php, отображение работы, сохранение в файл не Неустранимая ошибка: вызов функции-члена get () для не-объекта в C: \ wamp \ www \ ci \ application \ models \ site_model.php в строке 6 «Ошибка соединения сокета» при отладке PHP / JS на Aptana 3 Что означает этот синтаксис (page = $ page? $ Page: 'default') в PHP? Неустранимая ошибка: превышено максимальное время выполнения 500 секунд Загрузите img, не используя кнопку отправки или отмените в PHP и AJAX Как автоматически обновить таблицу, когда другая таблица обновляется на другом сервере mysql? Нет ответа с помощью Curl Получить информацию о операционной системе PHP не отображает ошибки, хотя display_errors = On PHP: удалить файл с любым расширением? Что такое Layout и что такое View в ZF? Когда и какие переменные следует использовать и почему? строка preg_split для многомерного массива Доступ к Phpmyadmin запрещен после перехода на более старые версии PHP / Apache на Wampserver

Google API Client "токен обновления должен быть передан или установлен как часть setAccessToken"

В настоящее время я столкнулся с очень странной проблемой, действительно, я слежу за этим же руководством ( https://developers.google.com/google-apps/calendar/quickstart/php ) из документации Google API. Я попробовал это дважды, в первый раз, когда он работает как прелесть, но после того, как токен доступа истекает, скрипт, предоставленный Google API, не смог его обновить.

TL; DR

Вот сообщение об ошибке:

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 

Вот часть php-скрипта из google, которую я изменил:

 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, я сделал эксперимент: вчера вечером я запускаю скрипт quickstart из ssh, чтобы проверить, работает ли он, и это действительно так, поэтому я решил проверить это утро, если он все еще работает просто как это было до того, как я спал, и это было не так, я думаю, что что-то не так с quickstart.php .

Надеюсь, кто-то может мне помочь, я уже проверил все остальные записи по теме, но они все устарели.

Я недавно получил ту же проблему, и я решил ее с этим.

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

Я объясняю ….. Refresh token не возвращается, потому что мы не принудительно утвердилиPrompt. В автономном режиме недостаточно. Мы должны принудительно утвердитьPrompt. Кроме того, после этих двух параметров необходимо установить 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; } 

Я столкнулся с такой же проблемой с новой библиотекой google api. Поиск решения привел следующую ссылку: RefreshToken Не получать отправки после того, как я получу новый токен google sheet API

Основываясь на этой информации, я изменил часть кода быстрого запуска, чтобы соответствовать моим потребностям. После первого разрешения с Google я получил drive-php-quickstart.json, который содержит refresh_token, срок действия которого истекает через 3600 секунд или один час. Ток обновления выдается только один раз, поэтому, если он потерян, требуется повторная авторизация. Итак, чтобы это всегда было в драйвере-php-quickstart.json, я сделал следующее:

 // 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; // save to file file_put_contents($credentialsPath, json_encode($accessTokenUpdated)); } 

просто обновление для тех, у кого возникли проблемы с этим сообщением, в основном это потому, что только первая команда fetchAccessTokenWithAuthCode () генерирует credencials, который содержит токен обновления (технически вечно действительный – нет 2-часовой проверки, если вы не отмените его). Когда вы получаете новый, он заменяет исходный, но он не содержит токен обновления, который ему нужен, поэтому в следующий раз, когда вам нужно обновить токен, он выйдет из строя. Это можно легко устранить, заменив функцию обновления на, например, следующим образом:

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

Теперь каждый раз, когда вы обновляете токен доступа, токен обновления также передается.

У меня были те же проблемы и, наконец, я пошел на это:

Предыстория:

Я получил ту же ошибку. Вот что я нашел:

Эта ошибка:

PHP Неустранимая ошибка: Uncaught LogicException: токен обновления должен быть передан или установлен как часть setAccessToken в /Library/WebServer/Documents/Sites/test/scripts/vendor/google/apiclient/src/Google/Client.php:267

Является ссылкой на токен доступа к обновлению (aka Refresh):

 $client->fetchAccessTokenWithRefreshToken($refreshTokenSaved); 

Почему это провалилось? Короче говоря, я понял, когда я распечатал массив $ accessToken, который исходит от декодирования этого json-файла (по быстрому стартовому коду, который вы отправили / который появился из Google)

Учетные данные / календарь-PHP-quickstart.json

Я обнаружил ошибку из-за того, как массив accessToken печатает, когда у меня print_r:

Array ( [access_token] => Array ([access_token] => xyz123 [token_type] => Носитель [expires_in] => 3600 [refresh_token] => xsss112222 [created] => 1511379484)

)

Решение:

$ refreshToken = $ accessToken ["access_token"] ["refresh_token"];

прямо перед этой строкой:

  $client->fetchAccessTokenWithRefreshToken($refreshToken); 

Я могу, наконец, обновить токен по мере необходимости, когда он истечет через час. Я думаю, что разработчики этой статьи предположили, что массив печатает как:

Массив ([access_token] => xyz123 [token_type] => Носитель [expires_in] => 3600 [refresh_token] => xsss112222 [created] => 1511379484)

поэтому они думали, что вы могли бы просто сделать $ accessToken ["refresh_token"]; Это неверно.

Теперь у нас есть допустимое значение для $ refreshToken, поэтому ошибка должна исчезнуть, если вы это сделаете. Я также обновил автора через ссылку обратной связи, чтобы сообщить об этом, если другие разработчики php столкнутся с этой проблемой. Надеюсь, это помогает кому-то. Мои извинения, если я отформатировал этот пост плохо, я новичок в SE, я просто хотел поделиться, поскольку я наконец получил это, чтобы работать.

Google обновил свой PHP Quickstart с помощью улучшенного метода для этого:

Ниже приведен фрагмент:

 // Exchange authorization code for an access token. $accessToken = $client->fetchAccessTokenWithAuthCode($authCode); $client->setAccessToken($accessToken); // Refresh the token if it's expired. if ($client->isAccessTokenExpired()) { $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken()); file_put_contents($credentialsPath, json_encode($client->getAccessToken())); } 

В моем случае я забыл установить тип доступа как «автономный», без которого токен обновления не генерировался.

 $client->setAccessType('offline'); 

Как только это будет сделано, образец кода, указанный в документации Google, будет работать.

 // Exchange authorization code for an access token. // "refresh_token" is returned along with the access token $accessToken = $client->fetchAccessTokenWithAuthCode($authCode); $client->setAccessToken($accessToken); // Refresh the token if it's expired. if ($client->isAccessTokenExpired()) { $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken()); file_put_contents($credentialsPath, json_encode($client->getAccessToken())); }