Skip to content

Instantly share code, notes, and snippets.

@webrobert
Last active October 26, 2023 16:33
Show Gist options
  • Save webrobert/615b7916c06f2974c3b39aff61a67c39 to your computer and use it in GitHub Desktop.
Save webrobert/615b7916c06f2974c3b39aff61a67c39 to your computer and use it in GitHub Desktop.
New up Dropbox tokens in Laravel

Dropbox, What, no way to get a long-lived token!?

So I was thinking how cool the Dropbox adapter is for filesystem. Then the token expired.

My app isn't client facing (It's an api for moving files between our systems). We don't have users that OAuth to get new tokens. I am wondering how others are handling this?

My solution (and tell me if there is a better method) was to add a cached call using the refresh method that is floating around the net... and the manual way since I just need the damn refresh_token (to new up tokens).

First, use your own <APP_KEY> and paste this url in a browser to get a code

https://www.dropbox.com/oauth2/authorize?client_id=<APP_KEY>&token_access_type=offline&response_type=code

Second, use the code with this Client post

Grab the refresh_token from the response...

return Http::asForm()
    ->withBasicAuth(config('dropbox.app_key'), config('dropbox.app_secret'))
    ->post('https://api.dropboxapi.com/oauth2/token', [
        'code' => '<THE_CODE_FROM_THE_URL>',
        'grant_type' => 'authorization_code',
    ])->json();

Finally, modify the DropboxServiceProvider to use the refresh_token

class DropboxServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $newToken = cache()->remember('dropbox_token', 13000, function () {
            return Http::asForm()
               ->post('https://api.dropbox.com/oauth2/token', [
                   'refresh_token' => config('services.dropbox.refresh_token'),
                   'client_secret' => config('services.dropbox.app_secret'),
                   'client_id' => config('services.dropbox.app_key'),
                   'grant_type' => 'refresh_token',
               ])
               ->json()['access_token'];
        });

        Storage::extend('dropbox', function ($app, $config) use($newToken) {
            $adapter = new DropboxAdapter(new DropboxClient($newToken));

            return new FilesystemAdapter(
                new Filesystem($adapter, $config),
                $adapter,
                $config
            );
        });
    }

Now dropbox will be satisified and we can live on beyond the short lived 4 hour tokens :/

Let me know if you found a better way, I've also posted this on Laracasts.

@Khal-ID
Copy link

Khal-ID commented Jul 22, 2023

Hello, I was wondering where should this piece of code go

return Http::asForm()
    ->withBasicAuth(config('dropbox.app_key'), config('dropbox.app_secret'))
    ->post('https://api.dropboxapi.com/oauth2/token', [
        'code' => '<THE_CODE_FROM_THE_URL>',
        'grant_type' => 'authorization_code',
    ])->json();

I'm using spatie's Flysystem adapter for the Dropbox API, I'd appreciate any help.

TIA

@lucionescu
Copy link

lucionescu commented Jul 25, 2023

Http::asForm() .....

Hi @Khal-ID ! This piece of code should be in controller:
If you want to send data as application/x-www-form-urlencoded content type request instead of application/json content type, use asForm() method.
@see https://laravelcode.com/post/create-http-requests-to-communicate-with-other-websites-in-laravel

@Khal-ID
Copy link

Khal-ID commented Jul 25, 2023

Http::asForm() .....

Hi @Khal-ID ! This piece of code should be in controller: If you want to send data as application/x-www-form-urlencoded content type request instead of application/json content type, use asForm() method. @see https://laravelcode.com/post/create-http-requests-to-communicate-with-other-websites-in-laravel

Thank you, I did figure it out after all. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment