Getting started with Box Python SDK and OAuth 2.0

Rui Barbosa
Box Developer Blog
Published in
6 min readAug 16, 2022

Client-side OAuth 2.0 is one of the easiest ways to authenticate a user for the Box API. It is an open standard designed to allow users to provide application access to their data in other applications.

In this article we will explore how to use Box OAuth 2.0 API to allow the user to grant access to their Box account to your app.

Requirements

Sample app

You can take a look at the end result of this exercise by cloning this repo, see the readme for more information.

Get a Box Developer Account

First you need to have a Box developer account.

If you already have one, you can skip ahead to the next step.

You may also skip this step if you have a standard Box account. Creating an application in the next step will upgrade your account to the developer type automatically.

Visit the developer account signup page. Fill out the text boxes and click Get Started.

You will receive a prompt to confirm your email address.

After clicking the confirmation url in your email, you will be taken to a login screen.

Once authenticated, you will see the Box Developer Console home screen.

Create a Box app

Visit the Box Developer Console.

Create a new application.

Creating an app

On the configuration tab, look for the OAuth 2.0 Credentials and make note of your client id and secret:

OAuth 2.0 Credentials

You also need to configure the Redirect URI. This will be where Box.com redirects the browser when sending the authorization code to continue the authorization process.

Finally you need to set the CORS Domain to what your app will be using.

Box OAuth 2.0

OAuth 2.0 is typically a 3 step protocol, so let’s dance.

Step 1: Get an authorization code

Essentially, this step is telling the Box API that your application wants to access resources from a Box user. The OAuth2 class from the Box python SDK has everything you need.

This method will simply return an URL to which you must redirect the user. A sample URL looks like this:

https://account.box.com/api/oauth2/authorize?
state=box_csrf_token_HMu2KmBMQUuPYNPI&
response_type=code&
client_id=w4a96f3tlv72rh9cxgt7jofad52rtrd9&
redirect_uri=https%3A%2F%2Fbox-dev.barduino.net%2Fui-elements-oauth%2Foauth%2Fcallback

State: Represents an unique string, hard to predict, never repeated, that will be used by your app to verify that the response was actually originated by this specific request.

Response type: We want to obtain an access code so the response type is always “code”

Client id: Represents your application unique identifier

Redirect URI: The entry point in your app which will handle the access code. This must match your box app configuration.

As you can see the OAuth2.Get_Authorization_URL, generates the complete URL and the state (aka CRSF token) for you. You should store the state on your app so that later you can verify it and you just need to redirect the browser to the authentication URL.

On my example I have a page to do just that:

Inviting the user to start this app authorization process:

The user is then redirected to the Box.com authorization pages:

The use must then login to Box.com and grant access to the app. Notice the permissions requested specified on the app configuration.

Step 2: Handle the OAuth callback

The browser is then redirected back to your app entry point, the OAuth call back, e.g.:

http://localhost:5000/oauth/callback?
state=box_csrf_token_DqbEFHUzaBxxx0l7&
code=JeRZftRFSvbTtZ3OXAyDHntpTUIkTPyq

Your app must now verify if the state on this redirect matches the state on the first request. If these do not match, you must start the process again.

This OAuth callback must also be able to handle errors, the most common being the user does not authorize your app.

Step 3: Getting an access token

Now that your app has an access code, you can exchange it for the proper access token.

The OAuth2 class from Box SDK also helps you with it:

Once we get the access token we can start sending requests to the API or use it in UI Elements.

Putting it all together

Although the Python Box SDK OAuth and Client classes have the capability to automatically refresh the tokens we still need a way to store these so we avoid the user having to keep authorizing your app.

The access token is valid for 60 minutes while the refresh token is valid for 60 days. Also the refresh token can only be used once.

So if the access token expires, the SDK will use the refresh token to get a fresh one and at the same time retrieve a new refresh token. If the refresh token expires, the user must re-authorize the app.

Also just like we do not store clear text passwords, we should not store unencrypted tokens.

Finally, UI Elements are JavaScript components that require an access token. Like any other JavaScript object, these can be inspected using the browser tools. We should downscope the user access token so that its permissions are only valid in the context of the UI Element.

Let us start with encryption.

Token encryption

Unlike passwords that are usually hashed making it impossible to get the password, the tokens need to be read from the database, so we have to use some form of encryption.

Encryption is a vast topic, and in this example I’m keeping it simple by using Python Fernet. My implementation is not ideal, but I’m just trying to make the point that you must encrypt the tokens.

These methods will be used when reading or writing a token.

Token storage

Each user will have a single pair of access and refresh tokens, so I’m storing them, encrypted on the user profile.

The Box Python SDK has a call back allowing you to execute a method every time a token is fetched or refreshed. You pass your callable to the store_tokens parameter.

The store_tokens() method:

Every time the OAuth class needs to get or refresh a token it will update the user profile.

Token downscoping

In order to get a more restrictive access token, we take the user access token and we “downscope” it using the specific grants for UI Elements. Each Element supports a variety of access levels.

Using the downscoped access token

So whenever the app needs an access token to use in an UI Elements, it can just call the method downscoped_access_token_get().

Using the Client class

If your app needs to use the API directly, it just needs to instantiate the Client class. This class is the gateway to the entire Box API.

For example, in the this demo, I need to check if the destination folder for the Uploader UI Element is created, in order to warn users about uploading files on their root folder.

Another example is in the previewer, where the app finds all files under the demo folder and passes that list to the previewer UI Element.

Find the sample app for the above tutorial in this repo.

This OAuth 2.0 example is combines the Box Python SDK and UI Elements.

This combinations gives your app the capability of allowing your users to interact with content stored at Box.com using their own security context, without forcing you to re-invent the wheel and design all the interfaces needed.

The Box Python SDK helps you manage the authorization process and also provides access to the entire Box.com API.

Happy Building!

--

--