cancel
Showing results forĀ 
ShowĀ Ā onlyĀ  | Search instead forĀ 
Did you mean:Ā 
Announcements
Want to learn some quick and useful tips to make your day easier? Check out how Calvin uses Replay to get feedback from other teams at Dropbox here.

Discuss Dropbox Developer & API

cancel
Showing results forĀ 
ShowĀ Ā onlyĀ  | Search instead forĀ 
Did you mean:Ā 

OAuth2 w/ refresh tokens for hybrid apps

OAuth2 w/ refresh tokens for hybrid apps

blobwriter
Explorer | Level 4
Go to solution

I have a little Cordova (I know react-native is cool now, but I strongly prefer Vue) app for Android+browser that uses Dropbox for sync, and for both platforms does auth by getting an OAuth2 bearer token using the javascript SDK (calling getAuthenticationUrl() w/ the appropriate callback, and navigating to the result).

 

From what I gather, the new API changes towards short-lived tokens mean that a) no matter what, browser apps will have to do a manual relogin every 4 hrs (though it might just be an insta-redirect with no manual user re-entry of credentials).

DropBoxInc's intent is that mobile apps that want long-lived access also request a refresh token, with which you can request future short-lived tokens.

 

But will the Javascript SDK (which I imagine is what most hybrid apps use) support this? I tried manually appending  

token_access_type=offline to the authentication URL returned by getAuthenticationUrl, but at the page: 

 

https://www.dropbox.com/oauth2/authorize?response_type=token&token_access_type=offline&client_id=$my...

 

I get 'Offline access disallowed for OAuth2 token flow ("response_type" can't be "token").'

 

But this would seem to mean that any cordova/capacitor/phonegap/hybrid apps (that rely on the javascript sdk for low-friction access to the dropbox API) are doomed with asking users to re-auth every 4hrs?

1 Accepted Solution

Accepted Solutions

Greg-DB
Dropbox Staff
Go to solution

No, such apps are not forced to have the user re-authorize every four hours. Client-side apps like this can request "offline" access to get refresh tokens if needed. There's an example of requesting offline access from a client-side app (a front-end browser app, in this sample) using the official Dropbox API v2 JavaScript SDK here.

 

The issue with the authorization URL you constructed is that the PKCE flow (which is how client-side apps can get offline access) is a form of the "response_type=code" flow, not "response_type=token".

 

I recommend letting the SDK build that URL for you, like in the example here. If you do want to build that directly though, you can find the full authorization documentation here.

View solution in original post

3 Replies 3

Greg-DB
Dropbox Staff
Go to solution

No, such apps are not forced to have the user re-authorize every four hours. Client-side apps like this can request "offline" access to get refresh tokens if needed. There's an example of requesting offline access from a client-side app (a front-end browser app, in this sample) using the official Dropbox API v2 JavaScript SDK here.

 

The issue with the authorization URL you constructed is that the PKCE flow (which is how client-side apps can get offline access) is a form of the "response_type=code" flow, not "response_type=token".

 

I recommend letting the SDK build that URL for you, like in the example here. If you do want to build that directly though, you can find the full authorization documentation here.

blobwriter
Explorer | Level 4
Go to solution

Thanks for the response Greg, always impressed with your responsiveness here.

 

So I got this working (the PKCE flow). However, having cached the access token in a local storage medium, requests to the Dropbox API  the next day  are rejected with a 401 error and "expired_access_token".

 

Ok, so I just have to write a little handler to catch it and ask for a new access_token using the refresh token (also stored). Simple enough. But how do I test this code? Can I request very-short-life-tokens (around 60s) just to test this handler? I know you can manually revoke access_tokens using authTokenRevoke(), but doing that seems to also revoke the associated refresh_token, so doesn't allow for testing of the (expired_access_token+valid_refresh_token) code path.

 

Edit: it seems that one should just pass the refresh token to the DropboxAuth object (which is, in turn, passed to the Dropbox object at instantiation), and DropboxAuth should(?) magically refresh access_tokens for me without having to write my own code. But just to clarify:

  1. the refresh_token is not itself single-use right? I don't have to somehow figure out when the DropboxAuth does a token refresh, in order to pull the (possibly new) refresh_token back out and overwrite the old refresh_token in storage?
  2. Instead, the actual case is that a new refresh_token is only received when you make the dbxAuth.getAccessTokenFromCode() call, using a valid pkce code?

 

 

 

Greg-DB
Dropbox Staff
Go to solution

There isn't a way to force an access token to expire soon or immediately, but I'll pass this along as a feature request. I can't promise if or when that might be implemented though. So, to test the actual 'expired_access_token' error for any particular new short-lived access token, you would need to wait four hours. (You don't need to wait to test the refresh flow itself though; you can perform a refresh at any point.)

 

And yes, that's correct, the SDK code will handle the refresh for you, and refresh tokens are not single-use and Dropbox does not return a new refresh token on every refresh, so you don't need to retrieve and store and new refresh token every time. You only get a refresh token once per authorization flow, from getAccessTokenFromCode.

Need more support?
Who's talking

Top contributors to this post

  • User avatar
    Greg-DB Dropbox Staff
  • User avatar
    blobwriter Explorer | Level 4
What do Dropbox user levels mean?