-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How can I refresh the access token? #115
Comments
Hello @johnRivs , I'm with the same issue, maybe we can think together. I tried cleanup from tinker with:
And don't works, but let's think in some points. I saw that GoogleAPI package did use the PSR I want mean that, I think is not about default cache defined of application with CACHE_DRIVER and the process running has your own cache. I dont try yet, but if the JOB run the cleanup command with One bad way to fix it fast, is try run |
This is what I ended up doing. I have a class responsible for getting a new access token: <?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
class Google
{
static function refreshToken()
{
$credentials = app('googleClient')->refreshToken(config('filesystems.disks.google.refreshToken'));
Cache::put('google-drive-credentials', $credentials);
}
} It's scheduled to run every 30 minutes: <?php
namespace App\Console;
use App\Services\Google;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
function schedule(Schedule $schedule)
{
$schedule->call(function () {
Google::refreshToken();
})->everyThirtyMinutes();
}
} In <?php
namespace App\Providers;
use App\Jobs\CompleteOrder;
use League\Flysystem\Filesystem;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Storage;
use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Queue\Events\JobProcessing;
use Hypweb\Flysystem\GoogleDrive\GoogleDriveAdapter;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
function register()
{
$this->app->singleton('googleClient', function () {
$client = new \Google_Client();
$client->setClientId(config('filesystems.disks.google.clientId'));
$client->setClientSecret(config('filesystems.disks.google.clientSecret'));
return $client;
});
}
function boot()
{
$this->prepareGoogleStorageForQueue();
$this->registerGoogleStorage();
}
function prepareGoogleStorageForQueue()
{
Event::listen(JobProcessing::class, function($event) {
if ($event->job->resolveName() === CompleteOrder::class) $this->registerGoogleStorage();
});
Event::listen(JobProcessed::class, function($event) {
if ($event->job->resolveName() === CompleteOrder::class) Storage::forgetDisk('google');
});
}
function registerGoogleStorage()
{
Storage::extend('google', function() {
app('googleClient')->setAccessToken(cache('google-drive-credentials')['access_token']);
$service = new \Google_Service_Drive(app('googleClient'));
$adapter = new GoogleDriveAdapter($service);
return new Filesystem($adapter);
});
}
} |
Hello my friend, I merged my way and your way and looks good to run without scheduled task to update token. I create one service to take about this: <?php
namespace App\Services\Google;
use App\Providers\GoogleDriveAdapter;
use Storage;
class GoogelDriveStorageAuth
{
public static function reloadGoogleStorage()
{
$accessTokenExpired = Storage::disk('google')->getDriver()
?->getAdapter()
?->getService()
?->getClient()
->isAccessTokenExpired();
if ($accessTokenExpired) {
\Log::info('GoogelDriveStorageAuth: access token expired - Storage Reloaded');
Storage::forgetDisk('google');
self::registerStorage();
}
}
public static function registerStorage()
{
\Storage::extend('google', function ($app, $config) {
$app; // to fix grumphp settings -> variable not used
$client = new \Google_Client();
$client->setClientId($config['clientId']);
$client->setClientSecret($config['clientSecret']);
/**
* Cache access token to reduce requests to Google
*/
if (\Cache::has('google access token')) {
$token = \Cache::get('google access token');
$client->setAccessToken($token);
}
if ($client->isAccessTokenExpired()) {
$refreshToken = $config['refreshToken'];
if ($refreshToken) {
$token = $client->fetchAccessTokenWithRefreshToken($refreshToken);
$client->setAccessToken($token);
\Cache::add('google access token', $token);
} else {
/**
* Invalid refresh token and or credentials
*
* Check cloud wiki on how to create an app and get credentials and refresh token
*/
throw new \Exception("Invalid refresh token, check cloud wiki");
}
}
$service = new \Google_Service_Drive($client);
$options = [];
$adapter = new GoogleDriveAdapter($service, $config['folderId'], $options);
return new \League\Flysystem\Filesystem($adapter);
});
}
} And, inside my Jobs, I put this line to, if necessary, reset the storage and re-auth: GoogelDriveStorageAuth::reloadGoogleStorage(); Thanks |
Yeah you can go that route as well. |
Oh yes! Great! Good point! |
I'm using this adapter inside a queue. Once it's registered via
Storage::extend()
, it'll be reused as long as the queue is running. Unfortunately, the access token expires in 1 hour and I can't seem to refresh it.What I was trying to do was to make a singleton out of the Google client used by the adapter then set up a scheduler task every 30 minutes where I do this
app('googleClient')->refreshToken(config('filesystems.disks.google.refreshToken'));
then cache the credentials and finallyapp('googleClient')->setAccessToken(cache('the access token'))
on every job I put in the queue. Didn't work. I've also tried to refresh the token on every job and it doesn't work either.The text was updated successfully, but these errors were encountered: