Authorization Code Flow

The Authorization Code Flow with PKCE is used for accessing an API on behalf of a customeruser. This flow requires the customeruser's consent to proceed and therefore cannot be used by backend-only systems without a user present. The authorization code flow can only be initiated once a customeruser has installed your app.

Step 1: Generate a Code Verifier & Code Challenge

For each authorization code request, a unique code verifier and code challenge are generated. The code verifier is a cryptographically random string and the code challenge is the SHA-256 hash of the code verifier. Together these values are used in place of a client secret so that requests can be made by public clients.

For more information see the OAuth Proof Key for Code Exchange spec.

Node.js Example
const crypto = require("crypto");

function base64URLEncode(buf) {
  return buf
    .toString("base64")
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=/g, "");
}

const verifier = base64URLEncode(crypto.randomBytes(32));
const challenge = base64URLEncode(
  crypto.createHash("sha256").update(verifier).digest()
);

Step 2: Obtain an Authorization Code

Redirect to the Authorization URL
https://{marketplace_url}/oauth/authorize?
  response_type=code&
  client_id={CLIENT_ID}&
  code_challenge={CODE_CHALLENGE}&
  code_challenge_method=S256&
  target={CUSTOMERORG_GUID}&
  state={STATE}

Request Parameters

Parameter
Value

response_type

code

client_id

Your app's client ID is found in the partner portal.

code_challenge

Unique value generated from the code verifier. See the example above.

code_challenge_method

S256

target or target_id

The unique partnerorg identifier passed as the target or target_id parameter to your app's installation URL.

redirect_uri

(optional; required if multiple URLs are defined for the app) Callback URL where Gobo will redirect after authorization has been granted. The Authorization Code will be available in the code parameter.

scope

(optional) A space-delineated list of scopes you are requesting. Gobo will only grant scopes that the app has already approved during installation. Leaving this blank will request all scopes to which the app has been approved.

state

(recommended) An arbitrary string your app adds to the request that Gobo will include when redirecting back to your redirect_uri. Guards against CSRF attacks. Also can be used to preserve state across requests.

Code Response

HTTP/1.1 302 Found
Location: {app_redirect_uri}?code={authorization_code}&state={state}

Step 3: Obtain an Access Token

A successful authorization code request will redirect to your provided redirect URI.

Now you can use the supplied code to obtain an access token.

Node.js Authorization Code Token Request
const axios = require("axios");

const CLIENT_ID = "5d24c3ac-ceae-405d-bf5f-12131fc92dc8";

app.get("/callback", (req, res) => {
  const code = req.query.code;
  if (!code) return res.sendStatus(404);
  
  // Verify that state matches what was sent to the authorization url.
  // Use state or other means to lookup the code verifier.
  const state = req.query.state;
  const verifier = "...";

  axios
    .post(
      "https://{marketplace_url}/oauth/token",
      new URLSearchParams({
        grant_type: "authorization_code",
        client_id: CLIENT_ID,
        code: code,
        code_verifier: verifier,
      }),
      {
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
      }
    })
    .then((response) => console.log(response.data))
    .catch((error) => console.error(error));
});

Request Parameters

Parameter
Value

grant_type

authorization_code

client_id

Your app's client ID is found in the partner portal.

code

code parameter provided by Gobo after redirecting to your redirect URI following a successful authorization code request.

code_verifier

Unique value used to create the code challenge provided during the authorization code request. See the example above.

redirect_uri

(optional; required if provided during authorization request) Callback URL where Gobo redirected during authorization.

Response

Client Credentials Response
{
    "access_token": "eyJhbGci...",
    "expires_in": 28800,
    "token_type": "Bearer",
    "scope": "foo bar",
    "refresh_token": "gr_..."
}

Step 4 (Optional): Refresh the Access Token When it Expires

When your access token expires, you can use the provided refresh token to obtain a new access token without having to go through the authorization code flow again. You will additionally be issued a new refresh token and the previous access token and refresh token will be invalidated.

Node.js Refresh Token Request
const axios = require("axios");

const CLIENT_ID = "5d24c3ac-ceae-405d-bf5f-12131fc92dc8";

// Get refresh token from database or other secure storage.
const refreshToken = "gr_...";

axios
  .post(
    "https://{marketplace_url}/oauth/token",
    new URLSearchParams({
      grant_type: "refresh_token",
      client_id: CLIENT_ID,
      refresh_token: refreshToken,
    }),
    {
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
    }
  })
  .then((response) => console.log(response.data))
  .catch((error) => console.error(error));

Request Parameters

Parameter
Value

grant_type

refresh_token

client_id

Your app's client ID is found in the partner portal.

refresh_token

Refresh token provided by Gobo alongside an access token obtained during an authorization code flow.

Response

Client Credentials Response
{
    "access_token": "eyJhbGci...",
    "expires_in": 28800,
    "token_type": "Bearer",
    "scope": "foo bar",
    "refresh_token": "gr_..."
}

It's bad practice to call the token endpoint to get a new access token every time you call an API. Gobo maintains rate limits and will throttle the number of requests to the token endpoint that come from the same token IP address. Apps should securely store and reuse the access and refresh tokens until they expire.

Last updated