# Authenticate to the API

{% stepper %}
{% step %}

### Assign configuration variables

Here, we set up the required configuration variables that are needed to authenticate with the API. Replace the 'CHANGEME' placeholders with your own values. These variables include the application name (APPNAME), application key (APPKEY), short name (SHORTNAME), and shared secret (SHARED\_SECRET). Additionally, we define a CACHE\_FILE variable that will store the access token we receive from the API.

{% tabs %}
{% tab title="Python" %}

```python
import jwt
import requests
import random
import time
import json
import os
from http.client import responsesimport requests

url = "https://api.netography.com/api/v1/auth/token"
APPNAME = 'CHANGEME
APPKEY = 'CHANGEME'
SHORTNAME = 'CHANGEME'
SHARED_SECRET = 'CHANGEME'

# path/filename to cache the bearer auth token 
CACHE_FILE = '~/.neto.token'
```

{% endtab %}

{% tab title="Shell" %}

```bash
#!/bin/bash
# (c) Netography 2023 All Rights Reserved 
# blyon

#~~ BEGIN Configuration ~~~

APPNAME=''
APPKEY=''
SHORTNAME=''
SHARED_SECRET=''

API_BASE_URL='https://api.netography.com/api/v1'

# path/filename to cache the JWT auth token 
CACHE_FILE='~/.neto.token'
chmod 600 CACHE_FILE

# ~~ END Configuration
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Prepare JWT request payload

In this step, we create a dictionary called 'payload' that will be used as the input for generating the JWT token. The payload includes the following fields:

iat: The current timestamp (issued at time) in seconds.\
jti: A random integer as a unique identifier for the token.\
appname: The application name.\
appkey: The application key.\
shortname: The short name.

{% tabs %}
{% tab title="Python" %}

```python
payload = {
    'iat': int(time.time()),
    'jti': random.randint(0,10000000),
    'appname': APPNAME,
    'appkey': APPKEY,
    'shortname': SHORTNAME
  }
```

{% endtab %}

{% tab title="Shell" %}

```bash
# Functin to create proper encoding 
base64_encode() {
  local input="$1"
  local encoded=$(printf '%s' "$input" | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n')
  echo "$encoded"
} 

# Cache Bearer token and re-use if not expired
jwt_valid=false
access_token=''

if [ -f "$CACHE_FILE" ]; then
  cache_data=`cat $CACHE_FILE`
  access_token=$(echo "$cache_data")
  jwt_valid=true
fi

if [[ $jwt_valid == false ]]; then

  # Generate the JWT request token

  DATE=`date +%s`
  payload=$(printf '%s' '{"iat":"'"$DATE"'","jti":"'"$RANDOM"'","appname":"'"$APPNAME"'","appkey":"'"$APPKEY"'","shortname":"'"$SHORTNAME"'"}' )

  # Static header fields.
  header='{
	"typ": "JWT",
	"alg": "HS256"
  }'

  # Create body

  header_base64=$(base64_encode "$header")
  payload_base64=$(base64_encode "$payload")
  header_payload_base64=$(printf '%s' $header_base64.$payload_base64)
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Encode JWT token and create HTTP POST request

We encode the JWT token using the payload and shared secret. The 'HS256' algorithm is used for signing the token. Then, we create a dictionary called 'body' with a single key, 'jwt', which holds the encoded JWT token. This body will be used in the HTTP POST request to the API.

{% tabs %}
{% tab title="Python" %}

```python
token = jwt.encode(payload, SHARED_SECRET, algorithm="HS256")

# Create the HTTP POST request with a JSON payload containing the JWT request token
body = {
  'jwt': token
}
```

{% endtab %}

{% tab title="Shell" %}

```bash
  signature=$(printf '%s' $header_payload_base64 | openssl dgst -sha256 -hmac "$SHARED_SECRET" -binary | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n')

  body="$header_base64.$payload_base64.$signature";
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Check for existing token, validate and handle API call

In this final step, we first check if a valid token already exists in the cache file (lines 31-42).

If it does, we will reuse it. If not, we send an HTTP POST request to the API endpoint (lines 44-53) to obtain a new access token.

The 'try' block (lines 44-52) handles the API call, parses the JSON response, and extracts the access token. If the response contains a valid access token, it is stored in the cache file for later reuse. In case of any errors during the API call, an error message is printed with the status code and the reason for the error (line 53).

This example demonstrates how to generate JWT tokens, authenticate with a SaaS API, and manage access tokens efficiently.34-57

{% tabs %}
{% tab title="Python" %}

```python
# Cache Bearer token and re-use if not expired
jwt_valid = False
access_token = None
if os.path.exists(CACHE_FILE):
  with open(CACHE_FILE) as f:
    cache_data = json.load(f)
  access_token = cache_data['access_token']
  expires_in = cache_data['expires_in']
  token_date = os.path.getmtime(CACHE_FILE)
  expire_timestamp = token_date + expires_in - 60 # account for some clock skew

  if (time.time() <= expire_timestamp):
    jwt_valid = True

if not jwt_valid:
	try:
		resp = requests.post(API_BASE_URL + '/auth/token', json=body)
 		data = resp.json()
 		access_token = data['access_token']
    with open(CACHE_FILE, 'w') as f:
    	json.dump(data, f)
    
	except Exception as e:
  	print(f"{str(resp.status_code)} {responses[resp.status_code]}.  Verify your configuration parameters")
{"success":true}
```

{% endtab %}

{% tab title="Shell" %}

```bash
  # Create the HTTP POST request with a JSON payload containing the JWT request token

  post=$(echo "{ "'"jwt"'": \"$body\" }" )

  resp=$(curl -s -X POST "$API_BASE_URL/auth/token" -H "Content-Type: application/json" -d "$post")

  if ! echo "$resp" | grep -q 'access_token'; then
    if echo "$resp" | jq -r '.message' 1>/dev/null 2>&1; then
      echo "Authentication Error: $(echo "$resp" | jq -r '.message')"
    else
      echo "Authentication Error: access_token not found in response"
    fi
    exit 1
  fi
  access_token=$(echo "$resp" | jq -r '.access_token')
fi

echo "bearer: $access_token"
echo -n  $access_token>$CACHE_FILE
{"success":true}
```

{% endtab %}
{% endtabs %}

{% endstep %}
{% endstepper %}
