0

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\nStack trace:\n#0 /var/www/drive/index.php(14): Google_Client->fetchAccessTokenWithRefreshToken(NULL)\n#1 {main}\n 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.

NekoLopez
  • 579
  • 1
  • 9
  • 28
  • I think this [SO post](https://stackoverflow.com/questions/39314833/google-api-client-refresh-token-must-be-passed-in-or-set-as-part-of-setaccessto) will help you with your problem. It also used a [quickstart](https://developers.google.com/calendar/quickstart/php) using PHP. – Jessica Rodriguez Sep 20 '18 at 06:41

1 Answers1

0

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));
 }
 ?>
NekoLopez
  • 579
  • 1
  • 9
  • 28