cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
We are making some updates so the Community might be down for a few hours on Monday the 11th of November. Apologies for the inconvenience and thank you for your patience. You can find out more 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: 

Re: Get refresh token from access token?

Get refresh token from access token?

nacredata
New member | Level 2
Go to solution

I can get an access token from the website at https://www.dropbox.com/developers/apps/info/****** for my server-based app. 

 

Those tokens seem to work for what I need, which is just to retrieve uploaded files and manage files in one directory. But those tokens seem to expire. How can I get a refresh token for this app? 

 

I tried:

 

 

curl https://api.dropboxapi.com/oauth2/token \
  -d code=<ACCESS_TOKEN>
  -d grant_type=authorization_code \
  -d redirect_uri=<REDIRECT_URL> \
  -u "<APP_KEY>:<APP_SECRET>"     

 

 

with the appropriate values but I get an error of "code doesn't exist or has expired" even when I try it right away after generating a new access token on the website. 

 

1 Accepted Solution

Accepted Solutions

Greg-DB
Dropbox Staff
Go to solution

It's not possible to get a refresh token from an access token. A refresh token can only be retrieved by authorizing the app via the OAuth app authorization flow. (The "Generate" button on an app's page on the App Console does not offer the ability to get a refresh token; that only returns an access token.)  To get a refresh token for a user account, an app should implement the OAuth app authorization flow, and request "offline" access. You can also find more information in the authorization documentation.

 

The /oauth2/token call you shared is failing because the "code" parameter there expects an "authorization code", not an access token.

 

If this is just for your own account though, you can process this manually without implementing the OAuth app authorization flow in your app's code/UI.

 

For instance, you could:

 

1. Make your OAuth app authorization URL like this: (plug in your app key in place of "APPKEYHERE").

 

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

 

 

2. Browse to that page in your browser while signed in to your account and click "Allow" to authorize it.

 

3. Copy the resulting authorization code.

 

4. Exchange the authorization code for an access token and refresh token like this, e.g., using curl on the command line: (plug in the authorization code from step 3 in place of "AUTHORIZATIONCODEHERE", the app key in place of "APPKEYHERE", and the app secret in place of "APPSECRETHERE").

 

curl https://api.dropbox.com/oauth2/token \
    -d code=AUTHORIZATIONCODEHERE \
    -d grant_type=authorization_code \
    -u APPKEYHERE:APPSECRETHERE​

 

 

The response will contain a short-lived access token and refresh token that you can then use as needed.

 

5. Store the returned refresh token. (It can be repeatedly re-used and doesn't expire by itself, though it can be revoked on demand.)

6. Use the returned short-lived access token to make API calls until it expires. For example, here's how a call to get the connected user information would look like: (plug in the access token from step 4 in place of "ACCESSTOKENHERE")

 

curl -X POST https://api.dropboxapi.com/2/users/get_current_account \
    --header "Authorization: Bearer ACCESSTOKENHERE"

 


7. Retrieve a new short-lived access token whenever needed like this, e.g., using curl on the command line: (plug in the refresh token from step 5 in place of "REFRESHTOKENHERE", the app key in place of "APPKEYHERE", and the app secret in place of "APPSECRETHERE")

 

curl https://api.dropbox.com/oauth2/token \
   -d refresh_token=REFRESHTOKENHERE \
   -d grant_type=refresh_token \
   -d client_id=APPKEYHERE \
   -d client_secret=APPSECRETHERE

 


8. Use the returned short-lived access token to make API calls until it expires. For example, here's how a call to get the connected user information would look like: (plug in the new access token from step 7 in place of "ACCESSTOKENHERE")

 

curl -X POST https://api.dropboxapi.com/2/users/get_current_account \
    --header "Authorization: Bearer ACCESSTOKENHERE"

 


Repeat steps 7 and 8 programmatically as needed.

 

Hope this helps!

View solution in original post

8 Replies 8

Greg-DB
Dropbox Staff
Go to solution

It's not possible to get a refresh token from an access token. A refresh token can only be retrieved by authorizing the app via the OAuth app authorization flow. (The "Generate" button on an app's page on the App Console does not offer the ability to get a refresh token; that only returns an access token.)  To get a refresh token for a user account, an app should implement the OAuth app authorization flow, and request "offline" access. You can also find more information in the authorization documentation.

 

The /oauth2/token call you shared is failing because the "code" parameter there expects an "authorization code", not an access token.

 

If this is just for your own account though, you can process this manually without implementing the OAuth app authorization flow in your app's code/UI.

 

For instance, you could:

 

1. Make your OAuth app authorization URL like this: (plug in your app key in place of "APPKEYHERE").

 

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

 

 

2. Browse to that page in your browser while signed in to your account and click "Allow" to authorize it.

 

3. Copy the resulting authorization code.

 

4. Exchange the authorization code for an access token and refresh token like this, e.g., using curl on the command line: (plug in the authorization code from step 3 in place of "AUTHORIZATIONCODEHERE", the app key in place of "APPKEYHERE", and the app secret in place of "APPSECRETHERE").

 

curl https://api.dropbox.com/oauth2/token \
    -d code=AUTHORIZATIONCODEHERE \
    -d grant_type=authorization_code \
    -u APPKEYHERE:APPSECRETHERE​

 

 

The response will contain a short-lived access token and refresh token that you can then use as needed.

 

5. Store the returned refresh token. (It can be repeatedly re-used and doesn't expire by itself, though it can be revoked on demand.)

6. Use the returned short-lived access token to make API calls until it expires. For example, here's how a call to get the connected user information would look like: (plug in the access token from step 4 in place of "ACCESSTOKENHERE")

 

curl -X POST https://api.dropboxapi.com/2/users/get_current_account \
    --header "Authorization: Bearer ACCESSTOKENHERE"

 


7. Retrieve a new short-lived access token whenever needed like this, e.g., using curl on the command line: (plug in the refresh token from step 5 in place of "REFRESHTOKENHERE", the app key in place of "APPKEYHERE", and the app secret in place of "APPSECRETHERE")

 

curl https://api.dropbox.com/oauth2/token \
   -d refresh_token=REFRESHTOKENHERE \
   -d grant_type=refresh_token \
   -d client_id=APPKEYHERE \
   -d client_secret=APPSECRETHERE

 


8. Use the returned short-lived access token to make API calls until it expires. For example, here's how a call to get the connected user information would look like: (plug in the new access token from step 7 in place of "ACCESSTOKENHERE")

 

curl -X POST https://api.dropboxapi.com/2/users/get_current_account \
    --header "Authorization: Bearer ACCESSTOKENHERE"

 


Repeat steps 7 and 8 programmatically as needed.

 

Hope this helps!

nacredata
New member | Level 2
Go to solution

Super helpful to have it spelled out like that. Thanks for taking the time. 

ValentinLutchanka
New member | Level 2
Go to solution

Hello, I have tried to follow your instructions, but I get a response error

 

{
    "error": "invalid_request",
    "error_description": "Bad \"Authorization\" header: 'ascii' codec can't decode byte 0xe2 in position 15: ordinal not in range(128)"
}

Здравко
Legendary | Level 20
Go to solution

Hi @ValentinLutchanka,

Sounds like you haven't put the actual access token, but something else... or if you typed it by hand is there any chance you entered something else? 🧐 Try copy/paste (it's more reliable 😉) and select with care borders of what you gonna copy.

Good luck.

olavolsf
Explorer | Level 3
Go to solution

Dear Greg,

 

I am having problems with getting the Refresh Token. I used the (c# version of the) curl command you mentioned in step 4

curl https://api.dropbox.com/oauth2/token \
    -d code=AUTHORIZATIONCODEHERE \
    -d grant_type=authorization_code \
    -u APPKEYHERE:APPSECRETHERE​

this is done with the following code: (bellow, "code" is the authorization code, blablabla1 is the appkey and blablabla2 is the appsecret.

 

private async Task<HttpResponseMessage> GetToken(string code)
{
    using (var httpClient = new HttpClient())
    {
        using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.dropbox.com/oauth2/token"))
        {
            var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("blablabla1:blablabla2"));
            request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");

            var contentList = new List<string>();
            contentList.Add("code=" + code);
            contentList.Add("grant_type=authorization_code");
            request.Content = new StringContent(string.Join("&", contentList));
            request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");

            var response = await httpClient.SendAsync(request);
            return response;
        }
    }
}

and then made a Json desserialization, like this

 

      HttpResponseMessage tokenResponse = await GetToken(AuthorizationKey);
      string tokenResult = await tokenResponse.Content.ReadAsStringAsync();
      var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(tokenResult);
      return values["access_token"];

 

However, the response object ("tokenResult") comes only with an Access Token, there is no Refresh Token in the dictionary. Let me show you the answer to the call:


{"access_token": "xxxxxxxxxx", "token_type": "bearer", "expires_in": 14400, "scope": "account_info.read account_info.write files.content.read files.content.write files.metadata.read files.metadata.write", "uid": "1337227873", "account_id": "dbid:xxxxxxxxxxxxxx"} (my bold)

 

there is no "refresh_token" to retrieve. Can you be so kind to help me with that? How can I retrieve Refresh Token in this scenario?

 

Best regards, Olavo.

Greg-DB
Dropbox Staff
Go to solution

@olavolsf To retrieve a refresh token, make sure you set 'token_access_type=offline' on the /oauth2/authorize URL initially. If you don't set that, it will default to 'online' in which case a refresh token is not returned.

 

There's an example earlier in this thread, but we also just published a new blog post showing how to use 'offline' access step-by-step (as well as an 'online' example for comparison).

olavolsf
Explorer | Level 3
Go to solution

Hi, Greg,

 

Thank you very much for your gidance. I did include the offline, but I was mispelling token_access_type=offline (the "type" was missing). Now everything is ok. I've got my beloved refresh token.

 

Best regards. Olavo.

 

 

cwearring
New member | Level 2
Go to solution

Really great - solved my problem immediately - thanks for sharing! 

Need more support?