PYTHON
Implement Webhook Receiver with Signature Verification
Create a Python Flask endpoint to securely receive and verify webhook payloads using an HMAC signature, ensuring data integrity and authenticity.
import hmac
import hashlib
import json
from flask import Flask, request, abort
app = Flask(__name__)
WEBHOOK_SECRET = "your_super_secret_webhook_key" # IMPORTANT: Use a strong, environment-variable-backed secret
@app.route('/webhook', methods=['POST'])
def handle_webhook():
signature_header = request.headers.get('X-Hub-Signature-256') # Common header name
payload = request.data # Raw payload bytes
if not signature_header or not payload:
abort(400, "Missing signature header or payload")
try:
# Extract the actual signature (e.g., 'sha256=abcdef...')
hash_algorithm, received_signature = signature_header.split('=', 1)
if hash_algorithm != 'sha256':
abort(400, "Unsupported signature algorithm")
except ValueError:
abort(400, "Invalid signature header format")
# Generate our own signature
generated_signature = hmac.new(
WEBHOOK_SECRET.encode('utf-8'),
msg=payload,
digestmod=hashlib.sha256
).hexdigest()
# Compare the two signatures securely
if not hmac.compare_digest(generated_signature, received_signature):
abort(401, "Signature mismatch - unauthorized")
# If verification passes, process the payload
try:
event_data = json.loads(payload)
print("Webhook received and verified successfully!")
print(f"Event type: {event_data.get('event_type')}")
print(f"Payload: {json.dumps(event_data, indent=2)}")
# Implement your event handling logic here
return {'status': 'success'}, 200
except json.JSONDecodeError:
abort(400, "Invalid JSON payload")
if __name__ == '__main__':
app.run(debug=True, port=5000)
How it works: This Python Flask snippet sets up a basic webhook endpoint that securely receives and processes incoming payloads. It's crucial for verifying webhook authenticity using HMAC signatures. The code extracts the signature from the `X-Hub-Signature-256` header, then generates its own signature using a shared secret key and the raw payload. By comparing these signatures with `hmac.compare_digest`, it prevents tampering and unauthorized requests, ensuring only legitimate webhooks are processed.