Authentication test
1. Introduction
Since every request must be signed using asymmetric keys, they must be encrypted before being sent, and responses must be decrypted to read their content.
2. Import libraries
In this Python example, we are using 5 libraries to perform the authentication process.
import json
from datetime import datetime
from hashlib import md5
from jose import jwt
import requests
3. Define variables
Define the variables method, endpoint, and content specific to each request (in this example, we will use the "POST" method for the "/test" endpoint with "json" content):
base_url = "https://api-auth.sandbox.qitech.app"
date = datetime.now().strftime("%a, %d %b %Y %H:%M:%S GMT")
method = "POST"
content_type = "application/json"
endpoint = "/test"
4. Build payload and header
Next, we define the header and body of the request according to the documentation of the API that will be used.
headers = {"alg": "ES512", "typ": "JWT"}
body = {"name": "QI Tech"}
5. Insert the private key and the integration key
api_key = "212edd2b-6520-4d6f-909d-6647a5617ff2"
client_private_key = '''-----BEGIN EC PRIVATE KEY-----
MIHbAgEBBEH7OuewosJfz4zKF+Gm0ogJxhb8G6LSMDVQQbFYz335mHCx9/Pr6Yk+
yYwsVozeXhlry3/vnUn1zCasU+4O+yseZ6AHBgUrgQQAI6GBiQOBhgAEAa46fN/2
8vI64shRhu9erMA6JLl3zHFX8gFHQrbb0g4IDfjXCKMCILiwdtL8QecstsgepTa7
yo1pTXOVNDbmLX2TAK38xb2Gv6OC+PA+5drF2wWajWbVLpR2R7mYEzr5HNIAJYHb
5C1jvM2ItK2R22HAbYfH25nsvGhkCGbrRNWQVF9g
-----END EC PRIVATE KEY-----'''
qi_public_key = '''-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQArwlIn6JHZfCz7eJ8hl/UzNDB0VDm
T0bROSbp/D6FxvjHyu7Xt31MHntld1jRv8WLyIMWdd77Yn0hyeHGxUNMHMwBJY9F
A9F0FbqNTPg7MaAl+qcXt8opRkb3x4KaszIGzQ+cdhMn7Er1ZLzhpbaaVn/jBFEh
f43JW4OatXK9QyyzZ7Q=
-----END PUBLIC KEY-----'''
6. Encrypt the body
encoded_body_token = jwt.encode(claims=body, key=client_private_key, algorithm="ES512")
7. Build encrypted payload
This variable contains the encrypted body that must be sent in the requests in the form
request_body = {"encoded_body": encoded_body_token}
8. Build MD5 hash for JSON header signature
Build MD5 hash for header signature using the encrypted payload (in this example, we use hashlib's MD5 as md5)
md5_encode = md5()
md5_encode.update(encoded_body_token.encode())
md5_body = md5_encode.hexdigest()
9. Format header date
IMPORTANT: The current date formatting for the header signature must be in the format "Fri, 13 May 2022 16:49:15 GMT".
base_url = "https://api-auth.sandbox.qitech.app"
//highlight-start
date = datetime.now().strftime("%a, %d %b %Y %H:%M:%S GMT")
// highlight-end
method = "POST"
content_type = "application/json"
endpoint = "/test"
10. Creating the string to be signed
Build the signature string containing the date and MD5 hash. The method and content_type of the request must also be defined (in this example, we will use the POST method with content in json format).
string_to_sign = method + "\n" + md5_body + "\n" + content_type + "\n" + date + "\n" + endpoint
11. Encrypt the header
Perform encryption using the JWT library (in this code example, we use jsonwebtoken as jwt in JavaScript)
claims = {"sub": api_key, "signature": string_to_sign}
encoded_header_token = jwt.encode(claims=claims, key=client_private_key, algorithm="ES512", headers=headers,)
12. Building the final header
authorization = "QIT" + " " + api_key + ":" + encoded_header_token
request_header = {"AUTHORIZATION": authorization, "API-CLIENT-KEY": api_key}
url = f"{base_url}{endpoint}"
Making the request
resp = requests.post(url=url, headers=request_header, json=request_body)
print(resp.json())