fbpx

Authentication

Authentication

In order to use the Daisycon API you will need to have an advertiser or publisher account (or both). If you don’t already have an account, you can visit Daisycon.com to create an account.

Method 1: oAuth with PKCE (recommended)

The Daisycon API supports oAuth 2.1 with PKCE for publisher and advertiser users (leadgeneration accounts will follow soon).

Authenticating via oAuth consists out of a series of steps.

  • Setup a developer account
  • Create an app and retrieve your client ID and client secret
  • Perform an authorization call and token exchange
  • Start using the API
  • Perform a refresh call
  • Common issues
  • Other documentation & code examples

 

Setup a developer account

Before you can start using oAuth you will need te setup a developer account in the Daisycon interface, currently it’s not possible to only setup a developer account, you will need to have access to either a a publisher or an advertiser account.

If you have not yet setup a developer account, checkout our documentation here

 

Create an app and retrieve your client ID and client secret

After creating a developer account, you will need to register an app in the Daisycon system. This will give you a client ID and a client secret to use on your oAuth authentication flow.

When creating an app, think clearly about the permissions the app needs, you would not want to give the app permissions to change your user and account settings if all it needs to do is fetch statistics.

The user that will create the oAuth connection also needs to have these permissions

If you have not yet created an app, checkout our documentation here

 

Perform an authorization call and token exchange

If you use server-to-server authentication we have a detailed guide available for oAuth over CLI

The oAuth process is a series of handshakes between your application/server and our API.

An oAuth connection is made for 1 publisher or advertiser account if you need access to multiple accounts. You will have to make multiple oAuth connections and store multiple refresh tokens!

Follow the guide below to setup your oAuth process.

  1. Start by generating a unique code verifier inside your client app for this request. The code verifier is must be a random string of the following characters: [A-Z] / [a-z] / [0-9] / “-” / “.” / “_” / “~”,with a minimum length of 43 characters and a maximum length of 128 characters. Be sure to store this code verifier in the users session (< href=”https://datatracker.ietf.org/doc/html/rfc7636#section-4.1″ target=”_blank” rel=”noopener noreferrer”>see rfc).
    • PHP example:

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      function randomString(int $length): string
      {
      	if ($length < 1)
      	{
      		throw new InvalidArgumentException('Length must be a positive integer');
      	}
      	$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~';
      	$length = strlen($chars) - 1;
      	$out = '';
      	for ($i  =0; $i < $length; ++$i)
      	{
      		$out .= $chars[random_int(0, $length)];
      	}
      	return $out;
      }
      
      $codeVerifier = randomString(random_int(43, 128));
      
    • Javascript example:

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      function generateRandomString(length) {
      	let randomString = '';
      	let allowedChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
      
      	for (let charNumber= 0; charNumber < length; ++charNumber) {
      		randomString += allowedChars.charAt(Math.floor(Math.random() * allowedChars.length));
      	}
      	return randomString;
      }
      
      function getRandomInt(max) {
        return Math.floor(Math.random() * max);
      }
      
      const codeVerifier = generateRandomString(getRandomInt(128));
      
  2. From the generated code verifier create a code challenge. This is the base64 url encoded sha-256 hash of the code verifier.
    • PHP example:

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      /**
       * Get hash
       *
       * @param string $code
       * @return string
       */
      private function hash(string $code): string
      {
      	return str_replace(
      		'=', 
      		'', 
      		strtr(
      			base64_encode(
      				hash('sha256', $code, true)
      			), 
      			'+/', 
      			'-_'
      		)
      	);
      }
      
      $codeChallenge = hash($codeVerifier);
      
    • Javascript example:

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      async function generateCodeChallenge(codeVerifier) {
      	let digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier));
      
      	return btoa(String.fromCharCode(...new Uint8Array(digest)))
      		.replace(/=/g, '')
      		.replace(/\+/g, '-')
      		.replace(/\//g, '_');
      }
      
      const codeChallenge = await this.generateCodeChallenge(codeVerifier);
      
  3. Redirect the user to the Daisycon oAuth URL. (Be sure to URL encode all query param values and make sure your redirect URI is registered to the app)
    https://login.daisycon.com/oauth/authorize?response_type=code&client_id=APP_CLIENT_ID&redirect_uri=APP_REDIRECT_URI&code_challenge=GENERATED_CODE_CHALLENGE

    * Optionally you can add the state parameter with your own data, this will be returned to the callback redirect url.

  4. After a successful login the oAuth will redirect back towards your redirect URI with a code (if passed in the request, your state)
    https://your-redirect.uri/and/path?code=OAUTH_CODE[&state=YOUR_STATE]
  5. With your received code make a server side POST call. (If your APP is a client side app, do NOT include your client secret!).
    • PHP example (with client secret):

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      function httpPost($url, $data)
      {
          $curl = curl_init($url);
          curl_setopt($curl, CURLOPT_POST, true);
          curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
          curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
          $response = curl_exec($curl);
          curl_close($curl);
          return $response;
      }
      
      $response = httpPost(
      	'https://login.daisycon.com/oauth/access-token',
      	[
      		'grant_type'    => 'authorization_code',
      		'redirect_uri'  => 'APP_REDIRECT_URI',
      		'client_id'     => 'APP_CLIENT_ID',
      		'client_secret' => 'APP_CLIENT_SECRET'
      		'code'          => 'RECEIVED_AUTH_CODE',
      		'code_verifier' => 'GENERATED_CODE_VERIFIER',
      	]
      );
      
    • Javascript example (without client secret!):

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      try
      {
          const data = {
              grant_type: 'authorization_code',
              code: 'RECEIVED_AUTH_CODE',
              client_id: 'APP_CLIENT_ID',
              client_secret: '', // leave empty
              redirect_uri: 'APP_REDIRECT_URI',
              code_verifier: 'GENERATED_CODE_VERIFIER'
          };
          const response = await fetch(url, {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json'
              },
              body: JSON.stringify(data)
          );
          console.log(response.json());
      } catch (e) {
          console.error(e);
      }
      
  6. You’ve now received an API access token that’s valid for 30 minutes and a refresh token that is valid for 30 days

    Example response:

    {
       "access_token":"string",
       "refresh_token":"string"
    }
    

 

Start using the API

Now that you have an access token and a refresh token you can start using our API by supplying the access token in the Authorization header.

Perform a refresh call

After 30 minutes your authentication token expired and you can no longer use it to perform API calls. But no worries! You’ve also received a refresh token. You can use this refresh token once to fetch another set of an access token and a refresh token. You can repeat this process indefinitely (or at least until someone revokes your access via the interface)

  • To refresh your session using the refresh token, perform another POST call and you’ll receive a new access token and refresh token. (A refresh token can only be used once, so be sure to store the new refresh token!)
    • PHP example (with client secret):

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      function httpPost($url, $data)
      {
          $curl = curl_init($url);
          curl_setopt($curl, CURLOPT_POST, true);
          curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
          curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
          $response = curl_exec($curl);
          curl_close($curl);
          return $response;
      }
      
      $response = httpPost(
      	'https://login.daisycon.com/oauth/access-token',
      	[
      		'grant_type'    => 'refresh_token',
      		'redirect_uri'  => 'APP_REDIRECT_URI',
      		'client_id'     => 'APP_CLIENT_ID',
      		'client_secret' => 'APP_CLIENT_SECRET'
      		'refresh_token' => 'RECEIVED_REFRESH_TOKEN',
      	]
      );
      
    • Javascript example (without client secret!):

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      try
      {
          const data = {
              grant_type: 'refresh_token',
              refresh_token: 'RECEIVED_REFRESH_TOKEN',
              client_id: 'APP_CLIENT_ID',
              client_secret: '', // leave empty
              redirect_uri: 'APP_REDIRECT_URI'
          };
          const response = await fetch(url, {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json'
              },
              body: JSON.stringify(data)
          );
          console.log(response.json());
      } catch (e) {
          console.error(e);
      }
      

 

Common issues

Below are a few of the commonly known issues

  1. I get the following error message: “Could not update token permissions due to the following constraint violation: User lacks service groups”
    • When you receive this error it means the app is asking for permissions that the authenticating user does not have. This is most commonly caused by asking for more permissions than the app needs or by asking for permissions in the custom group. Custom permissions are setup for specific publishers only, you should only request those if your user has access to them. To see or update what permissions your user has, log into the account as an account admin go to settings -> connected users and click the user used to authenticate. Also check your app under tools -> daisycon api -> your developer account -> your app.
  2. I get one of the following error message: “Client authentication failed” or “Invalid client”
    • This could be caused by various mistakes. Due to security constraints the error will not tell you exactly what mistake you made. We recommend checking the list below in this order.
      • Your client ID is incorrect
      • Your redirect_uri is incorrect, please note the redirect uri needs to be identical to what has been entered including any trailing slashes! Query parameters are ignored and do not need to be entered when configuring a redirect uri
      • Your code verifier is incorrect
  3. My app does not support user interaction, we have a server to server setup.
  4. Invalid protocol TLS.
    • As of april 3rd 2023, the Daisycon API only supports TLS 1.3. TLS 1.3 is the latest update to Transport Layer Security. This encryption protocol is faster (reduces HTTPS overhead) and is more secure than TLS 1.2.

Other documentation & code examples

We have a bunch of documentation available for you including code examples, feel free to add examples to our repositories by sending in pull requests.