> ## Documentation Index
> Fetch the complete documentation index at: https://developer.box.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth 2.0 without SDKs

export const Link = ({href, children, className, ...props}) => {
  const localizedHref = href;
  return <a href={localizedHref} className={className} {...props}>
      {children}
    </a>;
};

export const MultiRelatedLinks = ({sections = []}) => {
  if (!sections || sections.length === 0) {
    return null;
  }
  return <div className="space-y-8">
      {sections.map((section, index) => <RelatedLinks key={index} title={section.title} items={section.items} />)}
    </div>;
};

export const RelatedLinks = ({title, items = []}) => {
  const getBadgeClass = badge => {
    if (!badge) return "badge-default";
    const badgeType = badge.toLowerCase().replace(/\s+/g, "-");
    return `badge-${badge === "ガイド" ? "guide" : badgeType}`;
  };
  if (!items || items.length === 0) {
    return null;
  }
  return <div className="my-8">
      {}
      <h3 className="text-sm font-bold uppercase tracking-wider mb-4">{title}</h3>

      {}
      <div className="flex flex-col gap-3">
        {items.map((item, index) => <a key={index} href={item.href} className="py-2 px-3 rounded related_link hover:bg-[#f2f2f2] dark:hover:bg-[#111827] flex items-center gap-3 group no-underline hover:no-underline border-b-0">
            {}
            <span className={`px-2 py-1 rounded-full text-xs font-semibold uppercase tracking-wide flex-shrink-0 ${getBadgeClass(item.badge)}`}>
              {item.badge}
            </span>

            {}
            <span className="text-base">{item.label}</span>
          </a>)}
      </div>
    </div>;
};

<RelatedLinks
  title="REQUIRED GUIDES"
  items={[
{ label: translate("Select Auth Method"), href: "/guides/authentication/select", badge: "GUIDE" },
{ label: translate("Setup with OAuth 2.0"), href: "/guides/authentication/oauth2/oauth2-setup", badge: "GUIDE" }
]}
/>

## Overview

While leveraging an official Box SDK removes common hurdles of authentication,
it is possible to use the Box APIs without one. This guide reviews the steps to
manually complete the OAuth 2.0 flow.

1. Build the authorization URL
2. Redirect the user to the authorization URL
3. The user grants the application access to take actions on their behalf, which, if successful, provides an authorization code
4. Redirect the user back to the application
5. Exchange the authorization code for an Access Token

At the end of this flow, the application has an <Link href="/guides/authentication/tokens/access-tokens">Access Token</Link>, which
can be used to make API calls on behalf of the user.

<Note>
  The Access Token acquired through the OAuth 2.0 flow is inherently tied to the
  user who authorized the application.

  It is possible to <Link href="/guides/authentication/oauth2/as-user">act as another user</Link>
  using the `as-user` header.
</Note>

## Prerequisites

Before continuing you will need to complete the following steps:

* Create a Platform App within the Box Developer Console, which leverages the OAuth 2.0 authentication method.
* Navigate to the configuration tab for the application to copy the `client_id` and `client_secret` values.
* Ensure at least one redirect URI is configured in the configuration tab for the application.

## 1. Build authorization URL

An <Link href="/reference/get-authorize">authorization URL</Link> is comprised of the following parameters:

| Parameter                                                                         | Status      | Description                                                                                            |
| --------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------ |
| <Link href="/reference/get-authorize/#param-client_id">`CLIENT_ID`</Link>         | Required    | Obtained from the configuration tab of the Developer Console                                           |
| <Link href="/reference/get-authorize/#param-redirect_uri">`REDIRECT_URI`</Link>   | Optional    | Configured in the Developer Console and where the user is sent once granting access to the application |
| <Link href="/reference/get-authorize/#param-response_type">`RESPONSE_TYPE`</Link> | Required    | Always set to `code`                                                                                   |
| <Link href="/reference/get-authorize/#param-state">`STATE`</Link>                 | Recommended | Protects against cross-site request forgery                                                            |

<Warning>
  If you configured multiple redirect URIs for the application, the authorization
  URL must include the `redirect_uri` parameter matching one of the URIs
  configured in the developer console. If the parameter is not specified, the
  user will see a `redirect_uri_missing` error and will not be redirected back to
  the app.
</Warning>

At the minimum this URL will always use the format:

`https://account.box.com/api/oauth2/authorize`?`client_id=CLIENTIDHERE`&`response_type=code`

<CodeGroup>
  ```csharp .Net theme={null}
  var baseUrl = "https://account.box.com/api/oauth2/authorize";
  var clientId = "[CLIENT_ID]";
  var authorizationUrl = $"{baseUrl}?client_id={clientId}&response_type=code";
  ```

  ```java Java theme={null}
  String baseUrl = "https://account.box.com/api/oauth2/authorize";
  String clientId = "[CLIENT_ID]";
  String authorizationUrl = String.format("%s?client_id=%s&response_type=code", baseUrl, clientId);
  ```

  ```python Python theme={null}
  base_url = 'https://account.box.com/api/oauth2/authorize'
  client_id = '[CLIENT_ID]'
  authorizationUrl = f'{base_url}?client_id=${client_id}&response_type=code'
  ```

  ```js Node theme={null}
  var baseUrl = "https://account.box.com/api/oauth2/authorize";
  var clientId = "[CLIENT_ID]";
  var authorizationUrl = `${baseUrl}?client_id=${clientId}&response_type=code`;
  ```
</CodeGroup>

<Card href="/reference/get-authorize" arrow title="Learn more about the authorization URL" />

<Tip>
  If you have [Box Verified Enterprise][1] for your Box
  instance turned on, you
  may encounter an issue using the standard
  `account.box.com` base URL.
  Instead, use `ent.box.com` in place of `account.box.com`.
</Tip>

## 2. Redirect the user

Next, redirect the user to the authorization URL. The way this is done depends
on the application framework. Most framework documentation provides extensive
guidance on this topic.

If the authorization URL is not valid for the app specified, the user will see
an error page rather than a grant access screen. For example, if the
`redirect_uri` parameter in the authorization URL does not match one of the URIs
configured for your app, the user will see a `redirect_uri_mismatch` error.

<CodeGroup>
  ```csharp .Net theme={null}
  var authorizationUrl = $"{baseUrl}?client_id={clientId}&response_type=code";
  // redirectTo(authorizationUrl);
  ```

  ```java Java theme={null}
  String authorizationUrl = String.format("%s?client_id=%s&response_type=code", baseUrl, clientId);

  // response.redirect(authorizationUrl);
  ```

  ```python Python theme={null}
  auth_url = f'{base_url}?client_id=${client_id}&response_type=code'
  // redirect(auth_url, code=302)
  ```

  ```js Node theme={null}
  var authorizationUrl = `${baseUrl}?client_id=${clientId}&response_type=code`;
  // res.redirect(authorize_url)
  ```
</CodeGroup>

<Info>
  Additional query parameters can be passed along when redirecting the user to
  limit down the scope, or pass along some extra state. See the authorization
  reference documentation for more information.
</Info>

## 3. User grants application access

The user is redirected to their browser to log in to their account using the Box
UI. They are then presented with the list of requested scopes and the option to
approve the application to take actions on their behalf.

<Frame border center shadow width="400">
  <img src="https://mintcdn.com/box/J_EwM_J-GUl8Mc67/guides/authentication/oauth2/oauth2-grant.png?fit=max&auto=format&n=J_EwM_J-GUl8Mc67&q=85&s=4ca6c68db41c0276cf20d44b2a9ee76f" alt="Example OAuth 2.0 approval screen" width="796" height="890" data-path="guides/authentication/oauth2/oauth2-grant.png" />
</Frame>

When the user accepts this request by clicking **Grant access to Box**, the
browser will redirect to the configured redirect URL with a query parameter
containing a short-lived authorization code.

<Warning>
  If you configured multiple redirect URIs for the application, the authorization
  URL must include the `redirect_uri` parameter matching one of the URIs
  configured in the developer console. If the parameter is not specified, the
  user will see a `redirect_uri_missing` error and will not be redirected back to
  the app.
</Warning>

```sh theme={null}
https://your.domain.com/path?code=1234567
```

## 4. Exchange code

The provided authorization code is <Link href="/guides/api-calls/permissions-and-errors/expiration">valid for 30 seconds</Link> and must be
exchanged for an <Link href="/reference/post-oauth2-token">Access Token</Link> before expiration.

<CodeGroup>
  ```csharp .Net theme={null}
  using System.Net;
  using System.Net.Http;
  using Newtonsoft.Json;

  String authenticationUrl = "https://api.box.com/oauth2/token";
  var client = new HttpClient();

  var content = new FormUrlEncodedContent(new[]
  {
      new KeyValuePair<string, string>("grant_type", "authorization_code"),
      new KeyValuePair<string, string>("code", "[CODE]"),
      new KeyValuePair<string, string>("client_id", "[CLIENT_ID]"),
      new KeyValuePair<string, string>("client_secret", "[CLIENT_SECRET]")
  });

  var response = client.PostAsync(authenticationUrl, content).Result;

  class Token
  {
      public string access_token { get; set; }
  }

  var data = response.Content.ReadAsStringAsync().Result;
  var token = JsonConvert.DeserializeObject<Token>(data);
  var accessToken = token.access_token;
  ```

  ```java Java theme={null}
  String authenticationUrl = "https://api.box.com/oauth2/token";

  List<NameValuePair> params = new ArrayList<NameValuePair>();

  params.add(new BasicNameValuePair("grant_type", "authorization_code"));
  params.add(new BasicNameValuePair("code", "[CODE]"));
  params.add(new BasicNameValuePair("client_id", "[CLIENT_ID]"));
  params.add(new BasicNameValuePair("client_secret", "[CLIENT_SECRET]"));

  CloseableHttpClient httpClient = HttpClientBuilder.create().disableCookieManagement().build();

  HttpPost request = new HttpPost(authenticationUrl);
  request.setEntity(new UrlEncodedFormEntity(params));

  CloseableHttpResponse httpResponse = httpClient.execute(request);
  HttpEntity entity = httpResponse.getEntity();

  String response = EntityUtils.toString(entity);
  httpClient.close();

  class Token {
      String access_token;
  }

  Token token = (Token) gson.fromJson(response, Token.class);
  String accessToken = token.access_token;
  ```

  ```python Python theme={null}
  authentication_url = "https://api.box.com/oauth2/token";

  params = urlencode({
      'grant_type': 'authorization_code',
      'code': '[CODE]',
      'client_id': '[CLIENT_ID]',
      'client_secret': '[CLIENT_SECRET]'
  }).encode()

  request = Request(authentication_url, params)
  response = urlopen(request).read()
  access_token = json.loads(response)['access_token']
  ```

  ```js Node theme={null}
  const authenticationUrl = "https://api.box.com/oauth2/token";

  let accessToken = await axios
      .post(
          authenticationUrl,
          querystring.stringify({
              grant_type: "authorization_code",
              code: "[CODE]",
              client_id: "[CLIENT_ID]",
              client_secret: "[CLIENT_SECRET]",
          })
      )
      .then((response) => response.data.access_token);
  ```
</CodeGroup>

To learn how to use an Access Token visit our guide on <Link href="/guides/api-calls">Making API calls</Link>.

[1]: https://support.box.com/hc/en-us/articles/360043693554-Box-Verified-Enterprise-Supported-Apps

<RelatedLinks
  title="RELATED APIS"
  items={[
{ label: translate("Authorize user"), href: "/reference/get-authorize", badge: "GET" }
]}
/>

<RelatedLinks
  title="RELATED GUIDES"
  items={[
{ label: translate("Platform App"), href: "/guides/applications/platform-apps/index", badge: "GUIDE" },
{ label: translate("Select Auth Method"), href: "/guides/authentication/select", badge: "GUIDE" },
{ label: translate("Setup with OAuth 2.0"), href: "/guides/authentication/oauth2/oauth2-setup", badge: "GUIDE" }
]}
/>
