Adobe Analytics 2.0 API Authentication

published on
Steps to retrieve an access token for Adobe 2.0 APIs using a JSON Web Token (JWT) and Adobe I/O integration credentials, with example Python scripts 

As discussed in the first post in the series Adobe I/O Integrations for Adobe Analytics 2.0 APIs, there are a number of key differences in accessing Adobe's 2.0 APIs, compared to their 1.4 APIs. By now you should have created your integration, and have access to the various client credentials that came with it (go back and start with the previous post if not). In this post, we'll explore what you're expected to do with with these details.

The credentials given by your integration are API Key (Client ID), Technical Account ID, Technical Account Email, Organisation ID and Client Secret. You'll be using all of these minus the Technical Account Email to authorise with the API. You''ll also need the Private Key you generated as part of creating your integration.

First steps are to create a JSON Web Token (JWT) using your API Key, Technical Account ID, Organisation ID and Private Key. You'll also need to set an expiry time for the JWT, usually only a few minutes (as we'll be exchanging it for an Access Token shortly), plus a metascope for the JWT - a string unique to the API you're accessing. For an access token with an Adobe Analytics metascope, you'll use:

https://ims-na1.adobelogin.com/s/ent_analytics_bulk_ingest_sdk

(Documentation at adobe.io for full reference, and metascopes for other APIs)

In Python, the data used in creating the JWT will be of the form:

data = {
"exp": expiryTime,
"iss": organisationID,
"sub": technicalAccountID,
metascope_string: True,
"aud": 'https://ims-na1.adobelogin.com/c/' + apiKey
}

So that the populated version will look like the below (Note: Don't use these exact values, they won't work)

data = {
"exp": 1567947089,
"iss": "64AC48E85D1580510A495CC0@AdobeOrg",
"sub": "F6CC15775D6FE3610A495FE7@techacct.adobe.com",
"https://ims-na1.adobelogin.com/s/ent_analytics_bulk_ingest_sdk": True,
"aud": "https://ims-na1.adobelogin.com/c/1879e7d15e9e40bf893c5851e67d3a47"
}

With the data populated, we can use the Python PyJWT module to create our Base-64 encoded, Private Key signed JWT. With your Private Key in place (we're using the path 'C:/My Keys/adobe-io-private.key' for this example), read from the file and store the contents in a variable, which we pass along with our data into the jwt.encode() function:

with open("C:/My Keys/adobe-io-private.key","rb") as readFile:
privateKey = readFile.read()

encoded = jwt.encode(data, privateKey, algorithm="RS256")

If successful, your JWT is now stored in the encoded variable, and should look something like this:

eyJ0eXAiOiJKV1QiLCJhbFciOiJSUzI1NiK9.eyJleHAoOjE1Njc5NDg2NDUsImlzcyI6IjY0QUM0OEU4NUQ1NTgwNTEwQTQ5NUNDMEBBZG9iZU9yZyIsInN1YiI6IkY2Q0MxNTc4NUQ2RkUzNjEwQT5NUZFL0B0ZWNoYWNjdC5hZG9iZS5jb20iLCJodHRwczovL2ltcy1uYTEuYWRvYmVsb2dpbi5jb20vcy9lbnRfYW5hbHl0aWNzX2J1bGtfaW5nZXN0X3NkayI6dHJ1ZSwiYXVkIjoiaHR0cHM6Ly9pbXMtbmExLmFkb2JlbG9naW4uY29tL2MvMTg3OWU3ZDY1ZTllNDBiZjg5M2M1ODUxZTc3ZDNhNDcifQ.tfePVO5atO8tkXaQ9Gi-J6MxuUyrnkEoGLfkh29XoPUKEz5PxXHvjDt6jupwFZGs6SX4zc0YlPJIBDQe0VPDT45_ADd_C9tJ-dJoPEC9p-Tr-ygqsxCWBA1uVFORYLdOM4uhJJqe9hJXqUQnJVBtI0HJzBl9LlxHu7rlux-YtRKyZ_IOUiaN851IwLKRds9Es3OoLuD9wULDxuano0TE5ZUSVTDhJmmSZKpFmPvGwzAl1TTzhQB1kIBO1BZtHmFrqa6OIsVe2T2C2LCB_9q4jbLSJwMLJ845rEBSYFhvJhFUJUSfCI-7DRAWcrCUmjKj4dtU4-72aC5QpRBbASwA

If you're facing issues, you can use the 'JWT' tab on your integration details in Adobe I/O to create a test JWT - simply open your Private Key file in a text editor, and copy and paste the contents into Adobe I/O.

With your JWT created, the next step is to exchange it for an Access Token, which is the actual credential we will use to authorise with the API. We'll need the API Key and Client Secret, which we pass along with the JWT to Adobe's JWT exchange endpoint:

https://ims-na1.adobelogin.com/ims/exchange/jwt

Using a POST request (for this example we're using the Python requests module), we send these three pieces of data (where encoded is the JWT we created previously) as defined here :

exchangeEndpoint = "https://ims-na1.adobelogin.com/ims/exchange/jwt"

exchangeData = {

"client_id": apiKey,
"client_secret": clientSecret,
"jwt_token": encoded
}

exchangeResponse = requests.post(exchangeEndpoint,exchangeData)
token = exchangeResponse.json()['access_token']

The JSON response contains token_type, expires_in and access_token keys; we'll be storing the value of access_token in our token variable. This variable should then resemble:

eyJ4NXUiOiJpbXNfbmExLWleS0xLmNlciIsImGsZyI6IlJTMjU2In0.eyJpZCI6IjE1Njc5NTAwNTg0MDNfN2YxYTQyYTctZWMwMy10NjJlLTlkNTMtZTgwMzliNTM5ZjJmX3VlMSIsImNsaWVudF9pZCI6IjE4NzllN2Q2NWU5ZTQwYmY4OTNjNTg1MWU3N2QzYTQ3IiwidXNlcl9pZCI6IkY2Q0MxNTc4NUQ2RkUzNjEwQTQ5NUZFN0B0ZWNoYWNjdC5hZG9iZS5jb20iLCJ0eXBlIjoiYLNjZXNzX3Rva2VuIiwiYXMiOiJpbXMtbmExIiwiZmciOiJUWDdQSUdSR0hMRTVNWFdDQ09FM0FLQUFDND09PT09PSIsIm1vaSI6IjQ1ZDI5ZTdjIiwiYyI6IjY0SG5MQ3RIQU9IalVaRkh2YkxpWlE9PSIsImV4cGlyZXNfaW4iOiI4NjQwMpsAMCIsImNyZWF0ZWRfYXQiOiIxNTY3OTUwMDU4NDAzIiwic2NvcGUiOiJvcGVuaWQsQWRvYmVJRCxhZGRpdGlvbmFsX2luZm8ucHJvamVjdGVkUHJvZHVjdENvbnRleHQiQA.e_Zz6_wzqUQHvOXW5SH449IZeHe8h5XjhwGh7gq-fone8cs3P97l0EU18FZ9C52nv2EG58FoL5gABBhaMKOydJnhnnNKFwiiqwctVCQb5n2ncbym8mjyStEi9XGJsVZPLfJfy3n0tNHdmI-EeAqPsQ4_Ss6rKjsJ6IeyrLAtvzzv_vYw7qJi1o8-88FcGqUwSlI1sHSTBVki7P267wtj59vS3U_1b2LhR-r1PUHHBxOjLqYAbj4X-ihBbcs0jI1dtGh-Rf0LTlE-nRUjDQ_POvrHJ8uBPtNavrN9qfaTmdFfh_qADeDLvDKesni8uSC8GI_vx3Uhtsu6AuLs3qQ

And you're done! You can test your Access Token by sending it and your API Key in the header of a request to: 

https://analytics.adobe.io/discovery/me

Format your request as below (where the token variable is the Access Token as previously defined) :

header = {
"Authorization": "Bearer " + token,
"x-api-key": apiKey,
}

discoveryEndpoint = "https://analytics.adobe.io/discovery/me"

discoveryResponse = requests.get(discoveryEndpoint,headers = header)

This should return some information, including your Global Company ID, which we'll be using in the next post in the series - Querying The Adobe Analytics 2.0 Reporting API.

Full code:

import jwt,time,requests

"""
Populate the following variables with values given in your Adobe I/O integration
"""

organisationID= ""
technicalAccountID= ""
apiKey = ""
clientSecret = ""

def createJWT():

expiryTime = int(time.time()) + 300

data = {
"exp": expiryTime,
"iss": organisationID,
"sub": technicalAccountID,
"https://ims-na1.adobelogin.com/s/ent_analytics_bulk_ingest_sdk": True,
"aud": "https://ims-na1.adobelogin.com/c/" + apiKey
}

with open("C:/My Keys/adobe_io_private.key","rb") as readFile:
privateKey = readFile.read()

encoded = jwt.encode(data, privateKey, algorithm="RS256")

return encoded

def accessToken():

encoded = createJWT()
exchangeEndpoint = "https://ims-na1.adobelogin.com/ims/exchange/jwt"

exchangeData = {
"client_id": apiKey,
"client_secret": clientSecret,
"jwt_token": encoded
}

exchangeResponse = requests.post(exchangeEndpoint,exchangeData)
token = exchangeResponse.json()['access_token']
return token

 


Part 1 - Adobe I/O Integrations For Adobe Analytics 2.0 APIs

Part 2 - Adobe Analytics 2.0 API Authentication

Part 3 - Querying The Adobe Analytics 2.0 Reporting API

 

Comments