douduiyun6125 2018-09-18 23:55
浏览 96
已采纳

使用PHP的Google Drive API - 刷新令牌获取消息'刷新令牌的问题必须传入或设置为setAccessToken的一部分'

I'm trying to refresh token on my PHP script but It's not working yet. I'm using Google Drive API with PHP, my script works great in browser until token expires, checking in other sites I changed the code in this way:

index.php

<?php
require_once 'vendor/autoload.php';
if (!file_exists("client_id.json")) exit("Client secret file not found");
$client = new Google_Client();
$client->setAuthConfig('client_id.json');
$client->addScope(Google_Service_Drive::DRIVE);

if (file_exists("credentials.json")) {
$access_token = (file_get_contents("credentials.json"));
$client->setAccessToken($access_token);
//Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
    $refreshTokenSaved = $client->getRefreshToken(); 
    $client->fetchAccessTokenWithRefreshToken($refreshTokenSaved);
    $accessTokenUpdated = $client->getAccessToken();
    $accessTokenUpdated['refresh_token'] = $refreshTokenSaved;
    file_put_contents("credentials.json", json_encode($accessTokenUpdated));

     //I also tried in this way but it's also not working:
    //$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
    //file_put_contents("credentials.json", json_encode($client->getAccessToken()));
}

$drive_service = new Google_Service_Drive($client);
$files_list = $drive_service->files->listFiles(array())->getFiles(); //http://stackoverflow.com/questions/37975479/call-to-undefined-method-google-service-drive-filelistgetitems
echo json_encode($files_list);
} else {
  $redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . '/drive/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>

oauth2callback.php

<?php
require_once 'vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfigFile('client_id.json');
$client->setRedirectUri('https://' . $_SERVER['HTTP_HOST'] . '/drive/oauth2callback.php');
$client->addScope(Google_Service_Drive::DRIVE); //::DRIVE_METADATA_READONLY
if (! isset($_GET['code'])) {
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
 $client->authenticate($_GET['code']);
 $access_token = $client->getAccessToken();
 file_put_contents("credentials.json", json_encode($access_token));

 $redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . '/';
 header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>

But I still receive the message in logs:

PHP Fatal error: Uncaught exception 'LogicException' with message 'refresh token must be passed in or set as part of setAccessToken' in /var/www/drive/vendor/google/apiclient/src/Google/Client.php:266 Stack trace: #0 /var/www/drive/index.php(14): Google_Client->fetchAccessTokenWithRefreshToken(NULL) #1 {main} thrown in /var/www/drive/vendor/google/apiclient/src/Google/Client.php on line 266

I have to delete credentials.json and generate a new one executing index.php and being redirected to oauth2callback.php each hour, but that's not the idea.

How can I fix it?

I'd like to receive your help.

  • 写回答

1条回答 默认 最新

  • dongliuliu0385 2018-09-19 20:15
    关注

    Finally the token refresh works, I had to add this line $client->setAccessType("offline"); in oauth2callback.php, also delete and generate a new client_id.json to avoid errors.

    <?php
     require_once 'vendor/autoload.php';
     $client = new Google_Client();
     $client->setAuthConfigFile('new_client_id.json');
     $client->setRedirectUri('https://' . $_SERVER['HTTP_HOST'] . '/drive/resp.php');
     $client->addScope(Google_Service_Drive::DRIVE); //::DRIVE_METADATA_READONLY
    
     $client->setAccessType("offline");
    
     if (! isset($_GET['code'])) {
       $auth_url = $client->createAuthUrl();
       header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
     } else {
       $client->authenticate($_GET['code']);
       $access_token = $client->getAccessToken();
       file_put_contents("credentials.json", json_encode($access_token));
    
       $redirect_uri = 'https://' . $_SERVER['HTTP_HOST'] . '/drive';
       header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
     }
     ?>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?