Introducing Scoped Apps
We recently launched several permissions enhancements. You can read about them in the OAuth Guide or in the blog post, Now Available: Scoped Apps and Enhanced Permissions. The major changes to be aware of are the introduction of short-lived tokens, scopes, PKCE, and refresh tokens. For now, our App Console supports both legacy and scoped app creation, but may be turned off soon as we prepare to retire long-lived tokens on September 30th, 2021. This means that:
- You should review your apps permission tab to transition to scopes. (This does not require code changes).
- You should ensure your app works with short-lived access tokens. (This may require code changes).
Updating Permissions
When you go the Permissions tab in an app’s settings, the scopes will be pre-selected based on your app’s legacy access type. For example, apps using the Business API with Team auditing will have team_info.read, members.read, groups.read, and events.read already selected. Apps using the User API will have all user scopes pre-selected.
You can click through without making changes and your app will continue working. However, we strongly recommend deselecting the scopes your app doesn’t need, which results in better overall security and asking for less permissions from your users.
Determine required scopes
Make a list of endpoints used by your app. Look at each endpoint in the HTTP Reference documentation and record the “Required Scope”.
For example, pretend we’re migrating an app for an online photo editing tool. For each endpoint used by the app we're going to record the corresponding scope.
If you ensure that your app’s scopes match your list, then your app will have the exact permissions it needs to access those endpoints. API calls to an endpoint without the appropriate scopes will throw an error.
Programmatically set scopes
After migrating, you can test your app with a specific group of scopes by passing them in the authorization URL. This approach can be used to test groups of scopes before deselecting the ones that aren’t needed.
Migrate permissions to scopes
Inside the App Console, go to the Settings page of app using the legacy permission model and click the Permissions tab. Note the message in light blue with details about the migration process. Deselect the scopes that your app is not using. Exercise caution when deselecting scopes as you can break functionality that your app depends on. We recommend auditing your app for required scopes before deselecting the ones you don’t need. Additional scopes can be added or removed later as needed.
Click Migrate then Confirm. Note that this change does not impact existing tokens. Test your scopes by going through an authorization flow. Way to go—you’ve migrated your app to use scopes! Next, we recommend migrating to short-lived tokens as long-lived tokens will be deprecated in the future.
Updating Access Token Type
If your app handles errors with 401 status correctly and only calls the Dropbox API when users are interacting with it, then it shouldn’t need any code changes. If your app doesn’t properly handle 401 errors or needs to interact with the Dropbox API without user input (“offline” access), then it may require code changes.
Testing short-lived access tokens with token_access_type
Before migrating your app to short-lived tokens, we recommend testing them in your app. You can programmatically issue short-lived tokens with a small adjustment to your code—including token_access_type=online in your authorization URL.
https://www.dropbox.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&token_access_type=online
We recommend starting with this approach during migration, then, once you’re confident in your app’s behavior, update the default access token type to short-lived in the App Console. You can find more information about setting up the right authorization flow for your app in the OAuth Guide.
Handle authorization errors
When a user tries to access your app with an invalid token, redirect them to the authorization URL you use in your OAuth flow. If the user has already authorized the app (and is logged into Dropbox), then a new short-lived is issued and they’re redirected to your app without any input from the user. This process will result in more re-authorization flows than before, but will have minimal impact on the end user experience.
If your app only calls the Dropbox API when the user is actively interacting with the app (online access) and follows the OAuth best practice of prompting for re-authentication on a 401 error, then your app should not not require code changes to support short live tokens.
Implement refresh tokens
For apps that:
- Want long-term access regardless of whether a user is present (i.e. a mobile app that stays logged in)
- Want to interact with the Dropbox API when a user isn’t actively interacting with the app (“offline” access)
We offer a long-lived refresh_token that can be used to request a new, short-lived access token.
Request a refresh_token as part of your access token payload by declaring the token access type as offline (token_access_type=offline) as a parameter in your authorization URL:
https://www.dropbox.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&token_access_type=offline
Now, complete your authorization request to /oauth2/token
curl https://api.dropbox.com/oauth2/token \
-d code=<AUTHORIZATION_CODE> \
-d grant_type=authorization_code \
-d redirect_uri=<REDIRECT_URI> \
-u <APP_KEY>:<APP_SECRET>
The resulting payload contains a refresh_token:
{
"uid": "267161268",
"access_token": "Your_Access_token",
"expires_in": 14399,
"token_type": "bearer",
"scope": "files.content.read files.metadata.read sharing.read sharing.write",
"refresh_token": "LwlUmqpmGqgAAAAAAAAEYgRoVJoei4u9cC7cDHFBAp0Kkp2JNciPxQpNWGY",
"account_id": "dbid:AABuTtSGJM0ME3t4m85i1o3XqnmXvwH5I-A"
}
Now, when you request a new token from the /oauth2/token endpoint, set the grant_type to refresh_token and provide your refresh_token as a parameter:
curl https://api.dropbox.com/oauth2/token \
-d grant_type=refresh_token \
-d refresh_token=<YOUR_REFRESH_TOKEN> \
-u <YOUR_APP_KEY>:<YOUR_APP_SECRET>
Update default token type
[Update: Dropbox is no longer offering the option to create new long-lived access tokens, so the Access token expiration drop-down is no longer available.]
Inside the Settings page (accessed via the App Console) of a legacy app, locate the section for OAuth 2 settings. Newly created scoped apps will default to short-lived tokens.
Click the Access token expiration drop-down and select Short-lived. Now your app is using short-lived access tokens by default! Note that short-lived tokens will expire after a period of time which is “short”, but generally long enough for a reasonable web session. The amount of time that an access token is valid is returned in the expires_in parameter of the access token payload. If your app needs “offline” access, then refer to the Implement refresh tokens section above.
Retiring Legacy Tokens
On September 30th, 2021, Dropbox will retire the creation of long-lived access tokens — resulting in all new tokens being short-lived. For online-only apps that already handle re-authentication, users may experience more prompts for re-authentication. Apps that require background (“offline”) access but have not yet implemented refresh tokens will be impacted.