OAuth Guide

// By Dropbox Platform Team • Dec 07, 2020

Overview

When working with the Dropbox APIs, your app will access Dropbox on behalf of your users. You'll need to have each user of your app sign into dropbox.com to grant your app permission to access their data on Dropbox.

Dropbox uses OAuth 2.0, an open specification, to authorize access to a user’s data. Once completed by a user, the OAuth flow returns an access token to your app. This access token can be used by your app in subsequent API calls for that user. It should be passed with the Authorization HTTP header value of Bearer <oauth2-access-token>

Note that pre-built components (the Chooser, Saver, and Embedder) are built into the Dropbox web site, and rely on the end-user’s own Dropbox web session, so they don’t require an OAuth flow (or an access token).

Diagram

Here's a diagram of an OAuth flow:

Dropbox OAuth 2 diagram

OAuth 2 diagram

In this flow:

  • The user will be redirected to Dropbox to authorize your app to access their Dropbox data. 
  • After the user has approved your app, they'll be sent back to your app with an authorization code
  • Your application exchanges the authorization code for an access token that can be used to make secure calls to the Dropbox API (not shown)

Your application may then securely store the token for future use. Authorizations may be revoked by the user, whereas apps may revoke tokens they receive.

Dropbox API Permissions

Scopes

The Dropbox API uses OAuth scopes to determine the actions your application is allowed to perform on a user’s data. When you create your application in the App Console, you’ll choose from different scopes in the ‘Permissions’ tab

Screenshot of the Permissions tab in app settings for a Dropbox app

Permissions tab in app settings

The selected scopes are applied to your access token and determine which API calls your application is allowed to execute. This level of access is then communicated to the end user on the Dropbox app authorization page where the user consents to sharing their data.

Scopes are generally organized into major actions, often read and write, on major objects. These objects include:

  • Account Info
  • Files and Folders
  • Collaboration (sharing)

For applications using the Business API to operate on Teams, this also includes:

  • Team Info
  • Membership
  • Group Settings
  • Sessions
  • Team Data
  • The Event log

The scope required for any given API call is documented on the endpoint:

Required scope field on an endpoint of the Dropbox API

The required scope of an endpoint in the Dropbox API

Legacy App Types

Prior to the introduction of scopes, Dropbox API apps would select only their level of content access (described below). Business API apps would select from one of four permission types to determine the API calls they have access to:

  • Team information – Information about the team and aggregate usage data
  • Team auditing – Team information, plus the team's detailed activity log
  • Team member file access – Team information and auditing, plus the ability to perform any action as any team member
  • Team member management – Team information, plus the ability to add, edit, and delete team members

For compatibility, these deprecated app types remain selectable - but over the coming months we will begin to transition these apps to equivalent scopes. If you have an existing app on these types, don’t worry - this transition does not require code change.

Content Access

As you create your Dropbox application, you will also be prompted to select the scope of file access. Currently, these two options are:

  • App Folder: Your application will be able to take actions allowed by its scopes on data within its app folder only (in the /apps folder). This option is suitable for apps that export content or manage only their content.
  • Full Dropbox: Your application will be able to take actions allowed by its scopes on all data within the user’s Dropbox account. This permission is appropriate when your application needs to regularly access pre-existing content in the user’s account.

Minimal Access

Always ask for the least amount permissions required by your applications. Requesting more scope and content access than required may result in end users not accepting your OAuth request and could impact your app review process.

When using API scopes, you may also ask for minimal permissions at authorization time - then re-authorize at later time if and when your application requires more permissions from the user.

An example of different levels of scopes in a Dropbox app

Different levels of scopes on a user's authorization page

Remember, that pre-built components (the Chooser, Saver, and Embedder) are authorized on dropbox.com. You don’t need to manage their access - but the components can be used in conjunction with apps making API calls.

For example, you may discover that using these components for uploading, downloading, or previewing means that you don’t need to build functionality and request permission to do this in direct API endpoints.

Implementing OAuth

Setting up your app

Before you can get started, you'll need to register your app with Dropbox by creating a new app in the App Console. That page will guide you through the process of registering your app, selecting permissions, and obtaining an app key and secret (a.k.a. client_id and client_secret) and inputting redirect URIs.

Testing with a generated token

If you'd like to quickly test out the Dropbox APIs using your own Dropbox account before implementing OAuth, you can generate an access token from your newly created app in My apps by pressing the button that says "Generate" in the OAuth 2 section of your app settings page.

Screenshot of the OAuth 2.0 field in app settings with a Generate button

Generate button in OAuth 2.0 section of app settings

Keep in mind that this is only for your own account - you'll need to use the standard OAuth flow to obtain access tokens for other users.

Do not instruct your users to register their own Dropbox application to use your app - you just need to register your app once. Your end-users will connect to that app via the OAuth flow.

SDK Support

While doc will cover details of OAuth using HTTP calls, remember that Dropbox SDKs will take care of some of the OAuth 2 process automatically for you. Using one of these SDKs is recommended when possible. If you’re using one of the SDKs, see their tutorials and sample apps for reference after reviewing this guide.

Implementing Code Flow

The code flow is the recommended OAuth flow for all types of applications. In order to implement it, your application should:

  1. Construct a Dropbox authorization URL, with your application’s client_id and redirect_uri (if applicable) and specifying the response_type of code, and present it to the user
    Your Authorization URL should look like:
    https://www.dropbox.com/oauth2/authorize?client_id=MY_CLIENT_ID&redirect_uri=MY_REDIRECT_URI&response_type=code
  2. Wait for the end user to complete authorization on dropbox.com, whom is then redirected back to your URI with an authorization code in the query string
  3. Call the /oauth2/token endpoint with your app’s client_secret to exchange the code for an access token in order to make API calls
Graphic of the Dropbox OAuth 2 code flow

OAuth 2 code flow

As you configure redirects, remember:

  • You'll need to register the exact redirect URI(s) your app may use in the App Console for your application. Dropbox checks that the specified redirect_uri parameter in your Authorization URL matches one of the registered values at authorization time.
  • The redirect_uri is optional with the code flow - if unspecified, the authorization code is displayed on dropbox.com for the user to copy and paste to your app.
    • This extra step is less convenient for end users, but appropriate for apps that cannot support a redirect.
  • If your application needs additional context to complete the redirect, you may pass a state parameter the authorization URL - which will be returned as a query parameter in the redirect.

When using the code flow, your app must keep the client_secret secure. If your app can’t guarantee it’s security, then we recommend the use of PKCE as described below

Implementing PKCE

Some types of applications may be unable to keep the client_secret secure. This includes, but isn’t restricted to:

  • Desktop and mobile apps without a server (which need to include the secret in binaries)
  • Single-page applications in pure JavaScript
  • Hosted software deployed on untrusted or client infrastructure
  • Open source applications

PKCE is an open extension to OAuth 2.0, and solves this problem using dynamic codes instead of the static client_secret. Your app should construct a random code_verifier at authorization time of the user.

Incorporating these codes is similar to the code flow above, with the following additions: 

  • Your initial string (code_verifier) and generated value must follow the character restrictions of the spec
    • Regex of permitted characters: [0-9a-zA-Z\-\.\_\~], {43,128}
  • Include a code_challenge_method and code_challenge in your authorization URL. The code challenge method may be S256 or plain. Using S256 is the recommended approach.
    • If the challenge method is S256, then the code challenge is created by SHA256 hashing the code_verifier and base64 URL encoding the resulting hash
    • If the method is plain, then the code_verifier can be used without encryption
  • In your request to the token API, pass the code_verifier with your generated value instead of the client_id.
For more information about PKCE, please refer to the blog post, PKCE: What and Why?

Implicit Grant

Prior to the introduction of PKCE, the implicit grant flow was the recommended solution to applications which cannot secure a client_secret.

Dropbox continues to support this legacy flow for compatibility, but recommends PKCE for new apps. You should disable the implicit grant option in App Console if you are not using it.

In the implicit grant flow:

  • Your application constructs an authorization URL to dropbox.com for the user, with your application’s client_id and response_type and specifying the response_type of token
  • Once the user authenticates on Dropbox.com, they are redirected back to the specified URI with the access token in the URL fragment.

Your authorization URL should look like:

https://www.dropbox.com/oauth2/authorize?client_id=MY_CLIENT_ID&redirect_uri=MY_REDIRECT_URI&response_type=code

In this flow, the redirect_uri is required and verified in the App Console as described in the code flow.

The Dropbox mobile SDKs previously used the implicit grant, but have been updated to support PKCE.

Using User and Team Tokens

Apps that request only scopes from the User API will receive a token associated with the user that authorizes the app.

When an app requests team scopes for the Business API, the resulting token is associated with the team (rather than the administrator who authorized it). The user scopes requested as part of the team authorization define the calls that can be used when acting on behalf of a team member with Dropbox-API-Select-User.

Apps may request different scopes, per authorization, using the scopes parameter in the Authorization URL. For example, user apps may re-authorize to enable additional team functionality.

Using Refresh Tokens

Dropbox access tokens are short lived, and will expire after a short period of time. The exact expiry time of a token is returned by the token endpoint (or the redirect URI in implicit grant) - but is generally long enough for a reasonable web session.

If the token expires - throwing a 401 error - your application may simply re-authenticate as described above. If your token is expired, but the user is signed into Dropbox and their approval is still valid, the redirects will not require end-user input. A user’s approval remains valid until explicitly revoked.

Applications that require offline access to the API - meaning using the API when the end user is not actively interacting through your app - will not be able to prompt for re-authorization. These apps may instead use long-lived refresh tokens can be used to obtain new access tokens.

When using refresh tokens, your call to the /oauth2/token endpoint with the grant_type of authorization_code will return a short-lived access token and a refresh token, which should be securely stored.

Note: you’ll need to include token_access_type=offline as a parameter on your Authorization URL in order to return a refresh_token inside your access token payload.

To update your access token, call the /oauth2/token endpoint - specifying your refresh_token as a parameter and using the grant_type of refresh_token. The endpoint will return a new short-lived access token and a timestamp indicating its expiration time.

Working with refresh tokens is easier with an SDK. Helper methods accept the refresh token, and manage this update of the short-lived access token for you.

In the past, the Dropbox API used only long-lived access tokens. These are now deprecated, but will remain available as an option in the Developer console for compatibility until mid 2021.

For existing apps migrating to short-lived tokens, the token_access_type parameter on your authorization URL enables requesting short-lived tokens per-auth, allowing you to update your code without versioning issues in the Dropbox App Console.

Summary

There are several implementation options to OAuth - which is best for you will depend on the nature of your application. Dropbox recommends the following:

If your app is It should
A server-side web application that only calls the Dropbox API as users interact with it
Use the OAuth code flow with short-lived access tokens only (no refresh tokens).
A client-side web application (pure Javascript) Use the OAuth code flow with short-lived access tokens with PKCE (no refresh tokens).
A server-side application that requires background access. Use the OAuth code flow, with refresh tokens.
A client-side Desktop app or mobile app that requires background access Use the OAuth code flow with PKCE, with refresh tokens.
Currently using long-lived tokens Adopt short-lived tokens over the coming months
Currently using a legacy app permission type Convert to a scoped app in the app console

// Copy link