5

As the title says, I am trying to generate a refresh token, and then I would like to use the refresh token to get short lived Access tokens.

There is a problem though, in that I'm not smart enough to understand the docs on the dropbox site, and all the other information I've found hasn't worked for me (A, B, C) or is in a language I don't understand.

I have tried out all three examples from the github page, as well as user code from other questions on this site.

I haven't got anything to work.

The most I got was

Error: 400 Client Error: Bad Request for url: api.dropboxapi.com/oauth2/token

and

dropbox.rest.RESTSocketError: Error connecting to "api.dropbox.com": [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)

:(

Timi
  • 169
  • 1
  • 8
  • Version 1.6 of the `dropbox` library is very old; you should use the latest version, currently v11.25.0. You can find an example of processing the OAuth app authorization flow to get and use a refresh token with that here: https://github.com/dropbox/dropbox-sdk-python/blob/main/example/oauth/commandline-oauth-pkce.py – Greg Jan 10 '22 at 15:14
  • @Greg I changed back to the latest version and I tried all the examples out. I couldn't get any of them to work. The most I got was "Error: 400 Client Error: Bad Request for url: https://api.dropboxapi.com/oauth2/token". :( – Timi Jan 11 '22 at 10:40
  • I recommend posting a new question with the full details of whatever you're currently stuck on. – Greg Jan 11 '22 at 17:34
  • @Greg honestly I haven't made any progression. The only things I've done are try more code examples and still none of them have worked. – Timi Jan 13 '22 at 10:54
  • Please provide enough code so others can better understand or reproduce the problem. – Community Jan 18 '22 at 01:03
  • @Community I would if I had any code that got me close. :'( All the code I have tried, I have left a link to the source of. – Timi Jan 19 '22 at 14:45
  • there's NO END-to-END explanation or example how to get an access token. The tutorials end up on creating an app, which gives you API key+secret, but that's it. Where do you create a token? – Berry Tsakala Aug 22 '23 at 04:41

3 Answers3

27

Here is how I did it. I'll try to keep it simple and precise

Replace <APP_KEY> with your dropbox app key in the below Authorization URL

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

Complete the code flow on the Authorization URL. You will receive an AUTHORIZATION_CODE at the end.

Go to Postman and create a new POST request with below configuration

Key Value
code <AUTHORIZATION_CODE>
grant_type authorization_code

After you send the request, you will receive JSON payload containing refresh_token.

{
    "access_token": "sl.****************",
    "token_type": "bearer",
    "expires_in": 14400,
    "refresh_token": "*********************",
    "scope": <SCOPES>,
    "uid": "**********",
    "account_id": "***********************"
}

In your python application,

import dropbox

dbx = dropbox.Dropbox(
            app_key = <APP_KEY>,
            app_secret = <APP_SECRET>,
            oauth2_refresh_token = <REFRESH_TOKEN>
        )

Hope this works for you too!

Sparrow
  • 286
  • 4
  • 6
  • I got this to work, but do I have to repeat these steps constantly? Or does that refresh token last for good? I need to continually log in to dropbox as part of a scheduled job. – jgriffo1 Apr 20 '22 at 16:58
  • 2
    No, you don't need to repeat these steps again. Refresh tokens won't expire until you revoke them. Read [this](https://www.dropboxforum.com/t5/Dropbox-API-Support-Feedback/Oauth2-refresh-token-question-what-happens-when-the-refresh/td-p/486241) interesting thread from the dropbox forum – Sparrow Apr 22 '22 at 10:29
  • I have not found how to use Postman to create a new POST request, at least without registering. May be something has changed since you answered? Anyway, the snippet of orellabac made the trick. – Aristide Sep 07 '22 at 18:12
  • I'm getting "code doesn't exist or has expired" no matter what I do. My Access Code is freshly generated. – ColinDave Oct 04 '22 at 09:59
  • Thanks for @Sparrow your answer. I followed your steps and had a refresh token. I was wondering how to use it with requests module for the long-lived authorization? Is it possible to do that? Thanks a lot! – skippyho Jul 04 '23 at 15:51
9

The previous answer worked as a charmed, but if you need something quick to run, you can use this snippet:

#/bin/bash
echo -n "Enter APP_KEY" 
read APP_KEY

echo -n "Enter APP_SECRET" 
read APP_SECRET
BASIC_AUTH=$(echo -n $APP_KEY:$APP_SECRET | base64)

echo "Navigate to URL and get ACCESS CODE"
echo "https://www.dropbox.com/oauth2/authorize?client_id=$APP_KEY&token_access_type=offline&response_type=code"

echo -n "Return to this script once you have the ACCESS_CODE" 
read DUMMY

echo -n "Enter the ACCESS_CODE" 
read ACCESS_CODE_GENERATED

curl --location --request POST 'https://api.dropboxapi.com/oauth2/token' \
--header "Authorization: Basic $BASIC_AUTH" \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "code=$ACCESS_CODE_GENERATED" \
--data-urlencode 'grant_type=authorization_code'
orellabac
  • 2,077
  • 2
  • 26
  • 34
9

All methods above work, just want to post a pure python solution, which itself draws reference from the answers above.

  1. Find the APP key and App secret from the App Console.
  2. Run the following snippet (replace APP_KEY with the value obtained from last step) and complete the process in the browser to obtain Access Code Generated.
import webbrowser

APP_KEY = '<APP_KEY>'
url = f'https://www.dropbox.com/oauth2/authorize?client_id={APP_KEY}&' \
      f'response_type=code&token_access_type=offline'

webbrowser.open(url)
  1. Replace all APP_KEY, APP_SECRET, and ACCESS_CODE_GENERATED with the actual values in the following snippet. Run the snippet.
import base64
import requests
import json

APP_KEY = '<APP_KEY>'
APP_SECRET = '<APP_SECRET>'
ACCESS_CODE_GENERATED = '<ACCESS_CODE_GENERATED>'

BASIC_AUTH = base64.b64encode(f'{APP_KEY}:{APP_SECRET}'.encode())

headers = {
    'Authorization': f"Basic {BASIC_AUTH}",
    'Content-Type': 'application/x-www-form-urlencoded',
}

data = f'code={ACCESS_CODE_GENERATED}&grant_type=authorization_code'

response = requests.post('https://api.dropboxapi.com/oauth2/token',
                         data=data,
                         auth=(APP_KEY, APP_SECRET))
print(json.dumps(json.loads(response.text), indent=2))
chjch
  • 901
  • 9
  • 13
  • As a small correction, for me it worked after writting `f"Basic {BASIC_AUTH.decode()}"`. For some reason, as BASIC_AUTH is a bytes object, it was writting the b'' characters inside the string. Decoding it first removed these characters. – Carl HR Jul 25 '23 at 14:23