OAuth2 authentication

Prev Next

OAuth2 is the industry-standard protocol for authorization. It allows different applications to interact with each other on behalf of the user without the user giving out their credentials.

Prerequisites for configuring OAuth2 authentication

The OAuth2 authentication requires you to create a developer application on the data source platform, and you can then use the Client ID and Client Secret provided by the platform in your configuration.

When creating the application, it usually requires you to configure a callback URL, so the data source platform knows where to send the user after successful authentication.

The callback URL used by Supermetrics is always https://supermetrics.com/login-complete.

OAuth2 authentication flow

OAuth2 authentication flow consists of a few distinct steps that we will need to configure:

  • authorization: The initial request to send an authorization request to the data source API
  • tokenExchange: Request to exchange authorization code for an actual access token, as well as to receive a refresh token.
    • Access tokens usually have a relatively short lifetime, but they can be programmatically refreshed using a refresh token.
  • refresh: Request to fetch a new token before the old one expires.

Template OAuth2 configuration

Below you can find a template configuration that you can fill in with your own information for an easier start:

{
  "authentication": {
    "type": "oauth2",
    "description": "Example description shown to users in the authentication screen.",
    "oauth2": {
      "clientId": "[encrypted client ID]",
      "clientSecret": "[encrypted client Secret]",
      "tokenLifetime": 3600,
      "tokenJsonPath": "$[path to access token in JSON response]",
      "authorization": {
        "request": {
          "url": "[url to authorization endpoint]",
          "parameters": [
            {
              "name": "[parameter name]",
              "value": "[parameter value]"
            }
          ]
        }
      },
      "tokenExchange": {
        "request": {
          "method": "POST",
          "url": "[url to token exchange endpoint]",
          "body": {
            "type": "urlencoded_form",
            "formData": [
              {
                "name": "grant_type",
                "value": "authorization_code"
              },
              {
                "name": "code",
                "value": "{{oauth2.code}}"
              },
              {
                "name": "client_id",
                "value": "{{oauth2.client_id}}"
              },
              {
                "name": "client_secret",
                "value": "{{oauth2.client_secret}}"
              },
              {
                "name": "redirect_uri",
                "value": "{{oauth2.callback_url}}/"
              }
            ]
          }
        }
      },
      "refresh": {
        "request": {
          "method": "POST",
          "url": "[url to token refresh endpoint]",
          "body": {
            "type": "urlencoded_form",
            "formData": [
              {
                "name": "grant_type",
                "value": "refresh_token"
              },
              {
                "name": "refresh_token",
                "value": "{{oauth2.refresh_token}}"
              },
              {
                "name": "client_id",
                "value": "{{oauth2.client_id}}"
              },
              {
                "name": "client_secret",
                "value": "{{oauth2.client_secret}}"
              }
            ]
          }
        }
      }
    }
  }
}

Configuring OAuth2 authentication

We'll instruct you to configure OAuth2 authentication flow using Spotify Ads API as an example. The authentication details for the Spotify Ads API can be found here:

To configure OAuth2 authentication to Spotify Ads, we need to:

  1. Add authentication component with type oauth2.
  2. Add Client ID and Client Secret as encrypted values.
  3. Configure the Authentication endpoint and request under the authorization object.
  4. Define the JSON path to get the token in the response and define the lifetime for the token.
  5. Token exchange under tokenExchange object.
  6. Token refresh under tokenRefresh object.

Base configuration for OAuth2 authentication

Let's start by defining the base configuration for OAuth2 authentication type:

"authentication": {
  "type": "oauth2",
  "description": "Description shown to users during the authentication flow",
  "oauth2": {
    ...
  }
}

Client ID and Client Secret

First, we need to input Client ID and Client Secret for the app that we've registered to the data source platform.

Values for Client ID and Secret need to be encrypted before they are inputted to the configuration, as we don't want to store any sensitive information directly in the configuration. Encryption can be done in "Secret encryption" section within the Connector builder user interface.

Once we have encrypted the credentials and inputted them into the configuration, the config should look like this:

"authentication": {
  "type": "oauth2",
  "description": "Description shown to users during the authentication flow",
  "oauth2": {
    "clientID": "[encrypted client ID]",
    "clientSecret": "[encrypted client secret]",
    ...
  }
}

Authorization

Next, we'll configure the authorization object under the oauth2 object to define how the first authentication request is done. You can see the documentation on how Spotify Ads API requires the authentication request to be made in Spotify's documentation: Authenticate your Ads Manager account

The authentication request is done by adding the request object with the required url and parameters. You'll need to match the URL and parameters to the API you're working with, which in this case are the following:

  • client_id
  • response_type
  • redirect_uri
  • state (This is a parameter required by Supermetrics and provides protection against attacks such as cross-site request forgery (see RFC-6749))

The request url is configured as a string, and the parameters as an array, like in the example below. For most of the values, we want to use ready placeholders to ensure the values will always be correct. The configuration would look like this:

"authorization": {
  "request": {
    "url": "https://accounts.spotify.com/authorize/",
    "parameters": [
      {
        "name": "client_id",
        "value": "{{oauth2.client_id}}"
      },
      {
        "name": "response_type",
        "value": "code"
      },
      {
        "name": "redirect_uri",
        "value": "{{oauth2.callback_url}}"
      },
      {
        "name": "state",
        "value": "{{oauth2.state}}"
      }
    ]
  }
}

Token exchange

Next, we need to configure how the authorization code received after user authorization is exchanged to the access token. This can be done in the Spotify Ads API by making a POST request to the endpoint https://accounts.spotify.com/api/token with the following details:

  • Base64 encoded client ID and client secret as Authorization header.
  • Request body with following parameters:
    • grant_type with string value authorization_code
    • code with the code received from the previous request
    • redirect_uri with the callback URL of Supermetrics

This is configured as request object under tokenExchange object, and we will use placeholders for most of the values, and placeholder operations to have client ID and secret encoded with Base64 encoding.

The configuration will look like this:

"tokenExchange": {
  "request": {
    "url": "https://accounts.spotify.com/api/token",
    "method": "POST",
    "headers": [
      {
        "name": "Authorization",
        "value": "{{base64(oauth2.client_id, ':', oauth2.client_secret)}}"
      }
    ],
    "body": {
      "type": "urlencoded_form",
      "formData": [
        {
          "name": "grant_type",
          "value": "authorization_code"
        },
        {
          "name": "code",
          "value": "{{oauth2.code}}"
        },
        {
          "name": "redirect_uri",
          "value": "{{oauth2.callback_url}}"
        }
      ]
    }
  }
}

Token JSONpath and Token lifetime

Next, we will configure JSONpath to find the token from the response and the lifetime for the token. After calling the Spotify Ads API to authenticate, the response will look like this:

a785aecb-bd3c-431f-bd21-023717dfbbc2

We can see that the access token is provided in the parameter access_token, refresh token in refresh_token, and the lifetime of the token is 3600 seconds.

To find the access token, to know when to refresh it, and what refresh token to use, we need to configure the tokenJsonPath and tokenLifeTime properties under the oauth2 object and the refreshTokenJsonPath property under the tokenExchange object in the connector configuration.

  • tokenJsonPath is configured as a string with JSONpath to the field access_token in the response.
  • tokenLifeTime is configured as an integer with the number of seconds how long the token is valid.
    • Note: Token lifetime can also be defined to be read dynamically from the response using expiresInJsonPath property
  • refreshTokenJsonPath is configured as a string with JSONpath to the field refresh_token in the response.
    • Note: While the other configuration comes directly under oauth2 object, the refresh token configuration should be done under tokenExchange.

The configuration will look like this:

{
  "authentication": {
    "type": "oauth2",
    "description": "Description shown to users during the authentication flow",
    "oauth2": {
      "clientId": "[encrypted client ID]",
      "clientSecret": "[encrypted client secret]",
      "authorization": {
        "request": {
          ...
        }
      },
      "tokenExchange": {
        "request": {
          ...
        },
        "refreshTokenJsonPath": "$.refresh_token"
      },
      "tokenJsonPath": "$.access_token",
      "tokenLifetime": 3600
    }
  }
}

Now you should already have a finalized authentication where you have received the actual access token from the API, which you can already start using in reporting requests!

However, this access token is set to expire after a short time by the API, so we want to next configure the token refresh flow to ensure the token is automatically refreshed by our system.

Token refresh

Access tokens granted by OAuth2 flow are commonly set to expire after short time. In Spotify Ads API, the lifetime of the token is 3600 seconds which is 60 minutes. In order to ensure you don't need to authenticate again after every 60 minutes, we want to configure an automatic token refresh flow.

This is done by configuring the tokenRefresh object under the oauth2 configuration. Under tokenRefresh, we can define a request to be made to refresh the token.

The Spotify Ads API requires a POST request to the endpoint https://accounts.spotify.com/api/token with the following details:

  • Base64 encoded client ID and client secret as Authorization header.
  • Request body with following parameters:
    • grant_type with string value refresh_token
    • refresh_token with the refresh token received from the authentication step

The configuration for refresh token will look like this:

"refresh": {
  "request": {
    "url": "https://accounts.spotify.com/api/token",
    "method": "POST",
    "headers": [
      {
        "name": "Authorization",
        "value": "{{base64(oauth2.client_id, ':', oauth2.client_secret)}}"
      }
    ],
    "body": {
      "type": "urlencoded_form",
      "formData": [
        {
          "name": "grant_type",
          "value": "refresh_token"
        },
        {
          "name": "refresh_token",
          "value": "{{oauth2.refresh_token}}"
        }
      ]
    }
  }
}

Now you should have all the necessary configurations for a successful OAuth2 authentication!

Here you can see the full configuration for all the steps defined above:

{
  "authentication": {
    "type": "oauth2",
    "description": "Description shown to users during the authentication flow",
    "oauth2": {
      "clientId": "[encrypted client ID]",
      "clientSecret": "[encrypted client secret]",
      "authorization": {
        "request": {
          "url": "https://accounts.spotify.com/authorize/",
          "parameters": [
            {
              "name": "client_id",
              "value": "{{oauth2.client_id}}"
            },
            {
              "name": "response_type",
              "value": "code"
            },
            {
              "name": "redirect_uri",
              "value": "{{oauth2.callback_url}}"
            },
            {
              "name": "state",
              "value": "{{oauth2.state}}"
            }
          ]
        }
      },
      "tokenExchange": {
        "request": {
          "url": "https://accounts.spotify.com/api/token",
          "method": "POST",
          "headers": [
            {
              "name": "Authorization",
              "value": "{{base64(oauth2.client_id, ':', oauth2.client_secret)}}"
            }
          ],
          "body": {
            "type": "urlencoded_form",
            "formData": [
              {
                "name": "grant_type",
                "value": "authorization_code"
              },
              {
                "name": "code",
                "value": "{{oauth2.code}}"
              },
              {
                "name": "redirect_uri",
                "value": "{{oauth2.callback_url}}"
              }
            ]
          }
        },
        "refreshTokenJsonPath": "$.refresh_token"
      },
      "tokenJsonPath": "$.access_token",
      "tokenLifetime": 3600,
      "refresh": {
        "request": {
          "url": "https://accounts.spotify.com/api/token",
          "method": "POST",
          "headers": [
            {
              "name": "Authorization",
              "value": "{{base64(oauth2.client_id, ':', oauth2.client_secret)}}"
            }
          ],
          "body": {
            "type": "urlencoded_form",
            "formData": [
              {
                "name": "grant_type",
                "value": "refresh_token"
              },
              {
                "name": "refresh_token",
                "value": "{{oauth2.refresh_token}}"
              }
            ]
          }
        }
      }
    }
  }
}

Using OAuth2 token in requests

Now that you have configured a successful OAuth2 flow, you can start using the OAuth2 access token in other requests. For this, we'll be using placeholders, so we ensure all the requests will always use the latest refreshed token.

The token can be used in the request object using a placeholder {{user.access_token}} in anywhere in the configuration: in account fetching, reporting, and so on.

The configuration for it will usually look like this:

...
"request": {
"url": "http://...",
"headers": [
{
"name": "Authorization",
"value": "Bearer {{user.access_token}}"
}
],
...
}