Verifying Sender Requests
When events trigger a webhook, PlexTrac sends a POST request with the event payload to the configured URL. If a secret is provided during webhook setup, PlexTrac generates an HMAC-SHA256 signature using that secret and includes it in the x-authorization-hmac-256
header. Users can specify a secret when creating a webhook in the PlexTrac UI, enabling signature-based verification of incoming requests.
Generating the Signature
PlexTrac generates the signature using the following JavaScript code in the application:
const hmac = crypto.createHmac('SHA256', webhook.secret);
hmac.update(Buffer.from(JSON.stringify(payload)));
const signature = hmac.digest('hex');
Verifying the Signature in Python
To verify the signature in Python, follow these steps:
Extract the
x-authorization-hmac-256
header from the incoming request.Retrieve the webhook secret.
Convert the payload into a JSON string using
json.dumps()
with specific formatting to match JavaScript'sJSON.stringify()
.Compute the HMAC-SHA256 hash and compare it with the received signature using the secret.
Python Implementation (FastAPI Example):
import hmac
import hashlib
import json
from fastapi import Request
async def verify_webhook(request: Request, secret: str):
# Extract the signature from the request headers
hmac_header = request.headers.get("x-authorization-hmac-256")
if not hmac_header:
return False # Missing signature header
# Retrieve and format the JSON payload
response_payload = await request.json()
payload_str = json.dumps(response_payload, separators=(',', ':')) # Match JSON.stringify()
# Compute the HMAC-SHA256 hash
hmac_obj = hmac.new(secret.encode(), payload_str.encode(), hashlib.sha256)
sha256_hash = hmac_obj.hexdigest()
# Compare the computed hash with the received signature
return hmac_header == sha256_hash
Debugging Tips
If the generated hash does not match the received signature:
Ensure that the JSON formatting is the same as
JSON.stringify()
(useseparators=(',', ':')
).Log the raw request body before parsing JSON to confirm the received data is correct:
raw_body = await request.body()
print(f"Raw Body: {raw_body.decode()}")
Check for encoding mismatches when converting the JSON string.
Confirm that both systems use the same secret for hashing.
Last updated
Was this helpful?