Server side integration
Server side integration allows you to communicate with ZealiD backend to be able to upload, sign and retrieve documents or data.
First steps
There are few things before you get started...
Prerequisites for integrating ZealiD:
- Have ZealiD app
- Receive your client_id and client_secret
- use HMAC_STRING generator to be able to generate hmac_string for Authentication header in your requests
- use HMAC_REQUEST to generate and send an authenticated request
Below you can find a couple of different scripts for generating hmac_string or for sending hmac requests
#!/bin/bash
if [ $# -eq 5 ]
then
export LC_ALL=C.UTF-8
clientid=$1
clientsecret=$2
uripart=$3
method=$4
payload=$5
timestamp=$(date +%s)
nonce=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 60)
base="https://core-hermes.zealid.com"
fulluri="$base$uripart"
reqstr="$method $uripart"
auth_string="$clientid$nonce$timestamp$reqstr$payload"
hmacsig=$(echo -n $auth_string | openssl dgst -binary -sha512 -hmac "$clientsecret" | base64)
hmac="client_id=\"$clientid\",ts=\"$timestamp\",nonce=\"$nonce\",signature=\"$hmacsig\""
echo "HMAC_STRING $hmac "
else
echo "Five input params required:"
echo "1 - client_id"
echo "2 - client_secret"
echo "3 - request_url - everything after https://hermes-dev.zealid.com"
echo "4 - request_method"
echo "5 - request_payload"
fi
import sys
import secrets
import time
import base64
import hmac
import json
def hmac_string(method, url, client, payload=None):
request_method = method
full_path = '/' + '/'.join(url.split('/')[3:])
client_id = client['id']
secret = client['secret']
nonce = secrets.token_urlsafe(32)
ts = int(time.time())
request_string = f"{request_method} {full_path}"
auth_string = f"{client_id}{nonce}{ts}{request_string}{payload if payload else ''}"
signature = base64.b64encode(
hmac.new(
secret.encode("utf-8"),
auth_string.encode("utf-8"),
"sha512"
).digest()
).decode("utf-8")
hmac_string = f'client_id="{client_id}",ts="{ts}",nonce="{nonce}",signature="{signature}"'
return hmac_string
if len(sys.argv) != 6:
print("Five input params required:")
print("1 - client_id")
print("2 - client_secret")
print("3 - request_url - everything after https://hermes-dev.zealid.com")
print("4 - request_method")
print("5 - request_payload")
else:
clientid = sys.argv[1]
clientsecret = sys.argv[2]
uripart = sys.argv[3]
method = sys.argv[4]
payload = sys.argv[5]
base_url = "https://core-hermes.zealid.com"
hmac_string = hmac_string(method,
f"{base_url}{uripart}",
{"id": clientid, "secret": clientsecret},
payload
)
print(f"HMAC_STRING: {hmac_string}")
#!/bin/bash
if [ $# -eq 5 ]
then
export LC_ALL=C.UTF-8
clientid=$1
clientsecret=$2
uripart=$3
method=$4
payload=$5
timestamp=$(date +%s)
nonce=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 60)
base="https://core-hermes.zealid.com"
fulluri="$base$uripart"
reqstr="$method $uripart"
auth_string="$clientid$nonce$timestamp$reqstr$payload"
hmacsig=$(echo -n $auth_string | openssl dgst -binary -sha512 -hmac "$clientsecret" | base64)
hmac="client_id=\"$clientid\",ts=\"$timestamp\",nonce=\"$nonce\",signature=\"$hmacsig\""
curl $fulluri\
-X $method\
-H "Authorization: HMAC $hmac"\
-H "Content-Type: application/json"\
-d "$payload"
else
echo "Five input params required:"
echo "1 - client_id"
echo "2 - client_secret"
echo "3 - request_url - everything after https://hermes-dev.zealid.com"
echo "4 - request_method"
echo "5 - request_payload"
fi
import sys
import secrets
import time
import base64
import hmac
import json
import requests
def hmac_request(method, url, client, headers={}, payload=None):
request_method = method
full_path = '/' + '/'.join(url.split('/')[3:])
client_id = client['id']
secret = client['secret']
nonce = secrets.token_urlsafe(32)
ts = int(time.time())
request_string = f"{request_method} {full_path}"
session = requests.session()
request = requests.Request(method,
url,
headers=headers,
data=payload)
prepped = request.prepare()
payload = prepped.body
auth_string = f"{client_id}{nonce}{ts}{request_string}{payload if payload else ''}"
signature = base64.b64encode(
hmac.new(
secret.encode("utf-8"), auth_string.encode("utf-8"), "sha512"
).digest()
).decode("utf-8")
hmac_string = f'client_id="{client_id}",ts="{ts}",nonce="{nonce}",signature="{signature}"'
print(f"auth_string: {auth_string}")
print(f"hmac_string: {hmac_string}")
headers.update({"Authorization": f"HMAC {hmac_string}"})
prepped.headers.update(headers) # this is OK
response = session.send(prepped)
try:
result = response.json()
expect:
result = response.content
return result
if len(sys.argv) != 6:
print("Five input params required:")
print("1 - client_id")
print("2 - client_secret")
print("3 - request_url - everything after https://hermes-dev.zealid.com")
print("4 - request_method")
print("5 - request_payload")
else:
clientid = sys.argv[1]
clientsecret = sys.argv[2]
uripart = sys.argv[3]
method = sys.argv[4]
payload = sys.argv[5]
base_url = "https://core-hermes.zealid.com"
response = hmac_request(method,
f"{base_url}{uripart}",
{"id": clientid, "secret": clientsecret},
headers={"Content-type": "application/json"},
payload=payload
)
print(f"{response}")
How to use hmac_string generation script
How to:
- hmac_string generation script returns to you an hmac string that you need to include in the request Authentication header
- hmac_string generation requires the whole request information
- For more information about hmac and it's usage please refer to hmac guide
Be aware!
- For all examples we expect you to pass payload as JSON!
- Your request is expected to have Content-Type: application/json in headers!
- HMAC_STRING value can be different depending if json is sorted or not
- We recommend using hmac_string generators to generate hmac_string for API Reference tests
#For [get_token]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/get_token" "POST" "{\"grant_type\":\"authorization_code\",\"code\":\"HERMES_CODE\",\"redirect_uri\":\"https://example.com\"}"
#For [get_data]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/get_data" "POST" "{\"token\":\"HERMES_TOKEN\"}"
#For [get_documents]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/user/CUSTOMER_ID/documents" "GET" ""
#For [upload]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/upload/CUSTOMER_ID" "POST" "{\"content\":\"base64filecontent==\",\"digest\":\"sha1offile\",\"filename\":\"your_file_name.pdf\"}"
#For [upload_hash]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/upload/hash/CUSTOMER_ID" "POST" "{\"content\":\"hashstring\",\"hashname\":\"your_hash_name\"}"
#for [sign QRcode]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/sign" "POST" "{\"document_id\":\"DOCUMENT_ID\",\"title\":\"my_file.pdf\",\"redirect_url\":\"https://example.com\", \"customer_id\": \"CUSTOMER_ID\"}"
#For [get_token]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/get_token" "POST" "{\"grant_type\":\"authorization_code\",\"code\":\"YOUR_HERMES_CODE\",\"redirect_uri\":\"https://example.com\"}"
#For [get_data]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/get_data" "POST" "{\"token\":\"YOUR_HERMES_TOKEN\"}"
#For [get_documents]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/user/YOUR_CUSTOMER_ID/documents" "GET" ""
#For [upload]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/upload/YOUR_CUSTOMER_ID" "POST" "{\"content\":\"base64filecontent==\",\"digest\":\"sha1offile\",\"filename\":\"your_file_name.pdf\"}"
#For [upload_hash]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/upload/hash/CUSTOMER_ID" "POST" "{\"content\":\"hashstring\",\"hashname\":\"your_hash_name\"}"
#for [sign QRcode]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/sign" "POST" "{\"document_id\":\"YOUR_DOCUMENT_ID\",\"title\":\"my_file.pdf\",\"redirect_url\":\"https://example.com\", \"customer_id\": \"YOUR_CUSTOMER_ID\"}"
How to use HMAC request generation script
How to:
- HMAC request generation scripts accept input in the same format as hmac_string generators
- HMAC request generators actually executes HTTP(S) request with HMAC authentication
Be ware!
- For all examples we expect you to pass payload as JSON!
- HMAC_STRING value can be different depending if json is sorted or not
#for [get_token]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/get_token" "POST" "{\"grant_type\":\"authorization_code\",\"code\":\"HERMES_CODE\",\"redirect_uri\":\"https://example.com\"}"
#for [get_data]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/get_data" "POST" "{\"token\":\"HERMES_TOKEN\"}"
#for [get_documents]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/user/CUSTOMER_ID/documents" "GET" ""
#for [upload]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/upload/CUSTOMER_ID" "POST" "{\"content\":\"base64...\",\"digest\":\"sha1...\",\"filename\":\"your_file_name.pdf\"}"
#For [upload_hash]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/upload/hash/CUSTOMER_ID" "POST" "{\"content\":\"hashstring\",\"hashname\":\"your_hash_name\"}"
#for [sign QRcode]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/sign" "POST" "{\"document_id\":\"DOCUMENT_ID\",\"title\":\"my_file.pdf\",\"redirect_url\":\"https://example.com\", \"customer_id\": \"CUSTOMER_ID\"}"
#For [get_token]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/get_token" "POST" "{\"grant_type\":\"authorization_code\",\"code\":\"YOUR_HERMES_CODE\",\"redirect_uri\":\"https://example.com\"}"
#for [get_data]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/get_data" "POST" "{\"token\":\"YOUR_HERMES_TOKEN\"}"
#for [get_documents]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/user/YOUR_CUSTOMER_ID/documents" "GET" ""
#for [upload]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/upload/YOUR_CUSTOMER_ID" "POST" "{\"content\":\"base64...\",\"digest\":\"sha1...\",\"filename\":\"your_file_name.pdf\"}"
#For [upload_hash]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/upload/hash/CUSTOMER_ID" "POST" "{\"content\":\"hashstring\",\"hashname\":\"your_hash_name\"}"
#for [sign QRcode]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/sign" "POST" "{\"document_id\":\"YOUR_DOCUMENT_ID\",\"title\":\"my_file.pdf\",\"redirect_url\":\"https://example.com\", \"customer_id\": \"YOUR_CUSTOMER_ID\"}"
Retrieve your customer data and get ready for signing
To be able to upload, sign or retrieve documents or data, first of all, you need to authenticate yourself as a user
Prerequisites for actions with documents:
- Scan QR code with ZealiD app
- Retrieve your temporary HERMES_TOKEN
- Retrieve your personal data and customer_id
- Be aware - you will need this customer_id for actions with documents
Generating authentication QR code
How to:
- QR code scanning is initial step of your authentication which helps to map your identity with the help of your device
- To be able to scan QR code you need the ZealiD app and successfully pass onboarding steps
Be aware!
- your_client_id - The same client_id as you provide for HMAC authentication
- After scanning qrcode and successfully confirming your authentication request you will be redirected and you will receive HERMES_CODE as url parameter
- *Make sure you are targeting correct environment!
# NOTE: production environment
# Open in your browser:
curl https://core-hermes.zealid.com/mediator/web_embed/auth_link/start/hermes_orpheus/hermes_orpheus_provider/{your_client_id}
# NOTE: testing environment
# Open in your browser:
curl https://hermes-dev.zealid.com/mediator/web_embed/auth_link/start/hermes_orpheus_dev/hermes_orpheus_dev_provider/{your_client_id}
Steps:
1 - 2. Use the url provided above to GET a template with QR code
3 - 4. While QR code is on your screen - JS in browser is checking request status in server
5 - 7. Scan QR code with Your ZealiD App and confirm request with TouchiD or FaceiD
8. After successful confirmation you will be redirected and in new url you can find code=HERMES_CODE -> This is the HERMES_CODE that you will have to provide in get_token request
Expected response:
https://core-hermes.zealid.com/mediator/web_embed/auth_link/success/OKQQJZuQQWsh-DclxhwZDdo_DCd7LOSaqinIIjA35Ms?code=hermes_code_xHVSIv-A...
You are ready!
Congratulations!
- You now have HERMES_CODE which you can use to finish your authentication process and start working with your documents
- For further actions please refer to any of these documentations:
- DATA API in detail documentation where you can find all API calls explained
- API reference if you are more experience user
- Or hmac_request examples in this guide if you want to jump directly on testing from your computer
Updated about 4 years ago