cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
We've been busy working on some major updates to the Community, so check out what's changing, what’s staying the same and what you can expect from the Dropbox Community right here.

Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

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

Unable to get long lived access tokens.

Unable to get long lived access tokens.

OperationsDreaming
New member | Level 2
Go to solution

Hello there!

 

I'm trying to get an access token that doesn't expire. A long-lived access token. For now, when I generated an access token from the App Console, the session will expire after x hours and won't give me a refresh token either.

I've checked the authentication documentation: 

 

https://developers.dropbox.com/oauth-guide#implementing-oauth

 

But I can't find the Access Token Expiration like the documentation shows:

 

dropbox generate.png

 

 

Mine is displayed like this: 

 

Screen Shot 2022-03-22 at 11.08.10 AM.png


As you can see, the option for the Expiration is missing. 


So I kept looking and came across a similar question on the forums and I followed every step: 

https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Tokens-only-valid-for-4-hours-from-app-...

 

Still can't get a long-lived access token.

 

Here's a test code: 

 

 

 

access_token = "sl-ABC" # I want a long lived one.
app_key = "xyz"
dbxTeam: dropbox = dropbox.DropboxTeam(oauth2_access_token=access_token, app_key=app_key)
print('Dbx Team is: ', dbxTeam.as_user('dbmid:MY_USER_ID').users_get_current_account())

 

 

 

output:

 

 

 

{
'_oauth2_access_token':'sl....',
'_oauth2_refresh_token': None,
'_oauth2_access_token_expiration': None,
'_app_key': 'xyz',
'_app_secret': None,
'_scope': None,
'_max_retries_on_error': 4,
'_max_retries_on_rate_limit': None,

'_session': <requests.sessions.Session object at 0x1083b1730>,
'_headers': None,
'_raw_user_agent': None,
'_user_agent': 'OfficialDropboxPythonSDKv2/11.28.0',
'_logger': <Logger dropbox (WARNING)>,
'_host_map': {'api': 'api.dropboxapi.com',
'content': 'content.dropboxapi.com',
'notify': 'notify.dropboxapi.com'},
'_timeout': 100}

 

 


Any ideas on how to get a token that won't expire?

 

15 Replies 15

Greg-DB
Dropbox Staff
Go to solution

@marksmithhfx Thanks for following up with the additional information. The "GET" and "POST" are referring to the HTTP "method" for the HTTP request. Every HTTP request uses one of a number of methods, for various different use cases, with GET and POST being two of the most commonly used ones.

 

The Dropbox /oauth2/token endpoint in particular does require the use of the POST method. Using GET could cause the issue you're seeing.

 

Unfortunately I can't offer support for the "OAuth2" package you're using itself, as that's not made by Dropbox. You may need to refer to its documentation for information on configuring and debugging it. For instance, there may be a way to enable more verbose debugging output. Likewise, check how you might configure the appropriate HTTP method to use to make sure it uses POST for the request to /oauth2/token.

marksmithhfx
Explorer | Level 4
Go to solution

Thanks Greg, you have confirmed what I was suspecting. In order to covert the refresh token to a new sl.access token a new kind of method needs to be used (POST) which does not appear to be supported in the current version of the OAuth2 package I am using. I will prepare something to pass along to LiveCode so they can update their OAuth2 (if they want). Using sl.access tokens that require frequent re-authorization is not ideal, but given no other alternative, I'll hobble along for awhile and see what develops down the road. 

 

Cheers and thanks. 

Mark

 

 

 

marksmithhfx
Explorer | Level 4
Go to solution

Thanks Greg,

 

You know, I was thinking, what a shame Dropbox did not implement the refresh exchange process using the GET method. I am sure, since I have the ability to add additional parameters, that I could define a grant_type = "refresh_token" and a refresh_token parameter that contains the refresh token, and send that with the existing ClientKey and ClientSecret and get the result back on the same URI and all would be great. 

 

Do you know why Dropbox chose POST over GET in this case? 

 

PS you mentioned to check their documentation, but all it includes is the following:

 

Summary

Present an authorization dialog for any web service that supports OAuth2 Authorization Code Flow

 

pAuthURL - The URL to present for the authorization page. This can be obtained from the API documentation of the service being authorized.

 

pTokenURL - The URL to obtain the authorization token from once an authorization code is sent to the redirect uri. This can be obtained from the API documentation of the service being authorized.

 

pClientID - The application client ID obtained when setting up your application with the web service.

 

pClientSecret - The application client secret obtained when setting up your application with the web service.

 

pScopes - A comma delimited list of authorization scopes. Valid scopes will be found in the API documentation of the service being authorized. If empty the scope parameter will be omitted.

 

pPort - The port to use for the redirect uri. It is recommended to use the range 49152-65535.

 

pParams - An array of additional key -> value pairs of extra parameters to be sent to the authorization url. Some services implement additional options that require extra parameters.

 

Examples

constant kAuthURL = "https://slack.com/oauth/authorize"

constant kTokenURL = "https://slack.com/api/oauth.access"

constant kClientID = "XXXXXXXXX.XXXXXXXX"

constant kClientSecret = "XXXXXXXXXXXXXXXXXXXXX"

constant kScopes = "incoming-webhook"

 

OAuth2 kAuthURL, kTokenURL, kClientID, kClientSecret, kScopes, 54303

 

--- end

 

By tagging on an extra parameter (token_access_type = "offline") I was able to obtain a refresh token, but can't do anything with it. Unfortunately no mention of GET or POST. 

 

Mark

 

 

Greg-DB
Dropbox Staff
Go to solution

@marksmithhfx It looks like the use of POST for these requests is required in the OAuth 2 specification:

 

The client MUST use the HTTP "POST" method when making access token requests.

I'll send this along as a feature request to support GET as well, but I can't promise if or when that might be implemented (especially as it would be contrary to the specification).

marksmithhfx
Explorer | Level 4
Go to solution

Thanks Greg, but I would nix that. After looking at your post and the documentation again I realized that the LiveCode commands: 

 

put "offline" into tParams["token_access_type"]

OAuth2 kAuthURL, kTokenURL, kClientID, kClientSecret, kScopes, kPort, tParams

 

must be doing both a GET and a POST (the GET for authorization, and the POST for the access token) because, per the documentation:

 

/oauth2/token

METHOD  POST

This endpoint returns a JSON-encoded dictionary including fields below:

access_token String The access token to be used to call the Dropbox API.
expires_in String The length of time in seconds that the access token will be valid for.
token_type String Will always be bearer.
scope String The permission set applied to the token.
account_id String An API v2 account ID if this OAuth2 flow is user-linked.
team_id String An API v2 team ID if this OAuth 2 flow is team-linked.
refresh_token String If the token_access_type was set to offline when calling /oauth2/authorize, then response will include a refresh token. This refresh token is long-lived and won't expire automatically. It can be stored and re-used multiple times.

 

Which is exactly what I am getting from the OAuth2 command above. So it is my misunderstanding when I said it was not using POST. It's using both. Only problem is, it was written before the age of refresh_tokens so it doesn't know what to do with them.

 

I'll just leave it to the experts to sort out and hope it doesn't take too long.

Thanks again,

Mark

 

marksmithhfx
Explorer | Level 4
Go to solution

Hi Greg, the response came, and quicker than I was expecting. Also very DIFFERENT than I expected. We had previously been discussing the recommendation in the DB documentation:

 

curl https://api.dropbox.com/oauth2/token \
    -d grant_type=refresh_token \
    -d refresh_token=<REFRESH_TOKEN> \
    -u <APP_KEY>:<APP_SECRET>

 

But the result I got back from Livecode, which works perfectly, looks like this:

  -- given a refresh token in var tRefreshToken...

      set the httpHeaders to "Content-type: application/x-www-form-urlencoded" & \

            return & "Authorization: Basic " & base64encode(kClientID & ":" & kClientSecret)

      put "grant_type=refresh_token" & "&" & "refresh_token=" & tRefreshToken into tPost

      put "https://api.dropbox.com/oauth2/token" into tUrl

      post tPost to url tUrl

      put JSONToArray(it) into tAuth

      put tAuth[access_token] into tAccessToken 

 

Naw, I would have never figured that out. But it works. And I am grateful.

Thanks for your previous attempts at resolving this. 

Mark

 

 

 

Need more support?
Who's talking

Top contributors to this post

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