OAuth 2.0

Apps connect to Box using OAuth 2.0, the standard used by most APIs for authenticating and authorizing users. The following walkthrough will show you how to authenticate a user. There are also Box SDKs that include implementations of the OAuth2 grants used by Box, or client libraries available in a number of languages that you might find useful.

Customer using Active Directory, LDAP, Siteminder or ‘SSO’?

Is your customer asking that you make your application work with an Identity Provider or Single Signon system that sounds like alphabet soup? Googled it and it’s for SSO on a mainframe, or something from the dark ages of computing? No problem: Box has you covered! If you authenticate your application via Box’s OAuth 2.0, your application with automatically let the customer sign-on with their company credentials, just like they do with every other Box application. This also applies to popular commercial services like Okta, One Login, and Ping.

Initial Setup

Testing: When your app is set to ‘Development’ mode, you can set your redirect_uri to the following local http endpoints: http://127.0.0.1, http://0.0.0.0, and http://localhost.

Before you can start using OAuth2 with your application, you’ll need to tell Box a bit of information about your application

Redirect URI: The redirect URI is the URL within your application that will receive the OAuth2 credentials.

Scopes: Select the “Read and write all files and folders” scope if your application needs to perform operations on files and folders, such as creating, downloading, editing, and deleting files and folders. Select the “Manage an enterprise” scope if your application needs to perform enterprise management, such as creating, editing, and deleting users and groups, viewing admin logs, and creating collaborations for groups.

The First Leg

First, direct your user to https://app.box.com/api/oauth2/authorize through either a POST or a GET request with the following parameters:

Parameters: For POST, include the parameters in the POST body. For GET, include them as query parameters. In both cases, URL encode the parameters.

response_type
required

Whether the endpoint returns an authorization code. For web applications, a value of code should be used.

client_id
required

The client_id you obtained in the Initial Setup.

redirect_uri

An HTTPS URI or custom URL scheme where the response will be redirected. Must be registered with Box in the application console. Wildcard redirect_uri values are also accepted in the request as long as the base url matches the URI registered in the application console. A registered redirect_uri of https://www.myboxapp.com can be dynamically redirected to https://www.myboxapp.com/user1234 if passed into the request redirect_uri parameter.

box_login

[optional] The email address of the user that you want to have pre-populated in the login form

state
required

An arbitrary string of your choosing that will be included in the response to your application. Anything that might be useful for your application can be included. Box roundtrips this information back to your application, and stronglyrecommends that you include an anti-forgery token, and confirm it in the response to prevent CSRF attacks to your users.

A sample GET request could therefore look like:

GET https://app.box.com/api/oauth2/authorize?response_type=code&client_id=MY_CLIENT_ID&state=security_token%3DKnhMJatFipTAnM0nHlZA

The User Experience

At this point, you’ve forwarded the user to Box’s authorization page:

Your application doesn’t need to do anything here; Box handles authenticating the user and giving them feedback on any errors:

After successfully entering their credentials, the user will be taken to a consent page, to authorize your application to access their account.

After clicking either Grant or Deny, you’ll receive a response from Box, as outlined in the next section.

Handling the Response from Box

If the user clicked Grant in the previous screen, Box will redirect to the URI you specified earlier with a code parameter and a state parameter, if you included one. For example, if your redirect URI was https://www.sean.com/rose, Box would redirect to:

Authorization Code: The authorization code is only valid for 30 seconds.

However, if the user clicked Deny, you will receive a request with an error and error_description parameter, such as:

GET https://www.sean.com/rose?error=access_denied&error_description=The+user+denied+access+to+your+application

Assuming you got a Grant response, At this point you should verify that the CSRF security_token you received back is the same one you gave the user back in the First Leg. This will help make sure that it really is your user, and not a malicious script. If the code doesn’t match you should reject with a 401 code.

The following conditions may also cause an error:

invalid_request

The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.

unsupported_response_type

The authorization server does not support obtaining an authorization code using this method.
Check the value of the code param in your request.

access_denied

The resource owner or authorization server denied the request.

server_error

The device the user is trying to log in from is not authorized to access the user’s account.

temporarily_unavailable

Your device is being rate limited, you need to either decrease your rate of authorization requests, or wait a bit.

Error Handling: The error parameter will always be present, while the human readable error_description may not. Your code should rely on error.

Getting the Access Token

Once your application has completed the above section and gotten an authorization code, it’ll now need to exchange the authorization code for an access token from Box.

The last four (redirect_uri_mismatch,, internal_server_error, insecure_redirect_uri, invalid_redirect_uri) are not returned to the application. Instead, they are shown to the end user in a Box-generated error page, like this:Using the Access and Refresh TokensThe access_token is the actual string needed to make API requests. Each access_token is valid for 1 hour. In order to get a new, valid token, you can use the accompanying refresh_token. Each refresh_token is valid for one use in 60 days. Every time you get a new access_token by using a refresh_token, we reset your timer for the 60 day period and hand you a new refresh_token. This means that as long as your users use your application once every 60 days, their login is valid forever. To use the refresh_token to get a new access_token, make a POST request to https://app.box.com/api/oauth2/token with the following, URL encoded parameters:A sample cURL request would look like:

In this response, you’ll receive both a new access_token and refresh_token. The refresh_token you used to make this request is no longer valid. If an error occurs, you’ll receive a 400 Bad Request, along with of the errors listed in the Getting the Access Token section.Using Your Access Token with API V2Once you have a valid access_token, you can use it to make requests to API V2. All you need to do is set it in the Authorization header like this:

Authorization: Bearer {a valid access token}

If you were, for example, trying to get a user’s folder in V2, a full cURL request would look like this:

If the protected resource request does not include authentication credentials or does not contain an access token that enabled access to the protected resource, Box sets the WWW-Authenticate response header field. If the protected resource request included an access token and failed authentication, Box sets the “error” attribute to provide the client with the reason why the access request was declined. Box also includes the error-description attribute to provide developers a human-readable explanation that is not meant to be displayed to end users. The following codes can be returned as a value for the WWW-Authenticate header.Destroying TokensIf you would like to get rid of tokens for a user (e.g. if you have a ‘logout of Box’ button in your app), make a POST request to https://www.box.com/api/oauth2/revoke with the following URL encoded parameters:

client_id
required

The client_id used to create this tokenType: string

client_secret
required

The client_secret used to create this tokenType: string

token
required

The access_token or refresh_token to be destroyed. Only one is required, though both will be destroyed.Type: string

For example, to destroy access_token 1234 and its associated refresh_token, you would issue this request:

Your request did not contain a grant type.
The code parameter is missing for the authorization code grant type.
The refresh token has expired or is malformed.

unauthorized_client

The grant type is unauthorized for this client_id

Your application is not authorized to use this grant type

invalid_grant

Auth code doesn’t exist or is invalid for the client.
The authorization code has expired

Verify the authorization code is set correctly in your request.
Your application likely needs to get a new authorization code.

invalid_client

The client credentials are invalid

Verify that the client ID and secret are correct.

redirect_uri_mismatch

The redirect URI is missing or do not match

Either a redirect URI is not configured for your application or the URI in the request does not match the configured URI.

insecure_redirect_uri

The URI is either not a custom protocol or not HTTPS.

Your application sent a bad redirect URI i.e. HTTP instead of HTTPS

invalid_redirect_uri

The redirect_uri scheme is invalid per the RFC. A common problem is the first character being something besides a letter.

Your application sent an invalid URI.

HTTP Status

Error Code

What happened

400

invalid_request

The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed

401

invalid_token

The access token provided is expired, revoked, malformed or invalid for other reasons. The client may request a new access token and retry the protected resource request

403

insufficient_scope

The request requires higher privileges than provided by the access token