Using a Webhook SecretJuly 24, 2016
The recently released advanced webhooks include the ability to define a “secret” in your webhook, which will pass along with your webhook as a header called “X-Spark-Signature”. This can be used to validate a request is coming from the Spark API and not from some other origin – more info can be found at the bottom of this page.
In this blog, we’ll walk you through using the secret field, so you can start locking down your webhooks ASAP.
First, you’ll need to create a webhook.
Note the “secret” field in the list of options; to make it easy, we’ll use the passphrase listed in the example and set it to:
Next you’ll need to code up some logic that checks the secret when the webhook’s data is received. The following script shows very simple validation – just prints out a true if the secret matches. Here’s the Python code:
from itty import * import hashlib import hmac @post('/') def index(request): """ When messages come in from the webhook, they are processed here. X-Spark-Signature - The header containing the sha1 hash we need to validate request.body - the Raw JSON String we need to use to validate the X-Spark-Signature """ raw = request.body #Let's create the SHA1 signature #based on the request body JSON (raw) and our passphrase (key) hashed = hmac.new(key, raw, hashlib.sha1) validatedSignature = hashed.hexdigest() print 'validatedSignature', validatedSignature print 'X-Spark-Signature', request.headers.get('X-Spark-Signature') print 'Equal?', validatedSignature == request.headers.get('X-Spark-Signature') return "true" #Replace this with the secret phrase you used in the webhook creation key = "somesupersecretphrase" port = 10007 run_itty(server='wsgiref', host='0.0.0.0', port=port)
Which can also be grabbed from Github.
Note the “key” field is the secret defined earlier when the webhook was created, which if it matches what’s sent in the webhook, will print ‘True’.
This app alone won’t do much – all it’s going to do is confirm “Yep, that’s the right secret!” and then end. But if we combo it with our recent Bot example (Spark bot demo blog | Github repo) then we can validate the secret and use it in an if / else statement. If the secret matches, keep going, if it does not, end immediately. The complete code combining the above validation script and the bot script can be found on Github as well.
From that app, here’s a snippet showing the relevant logic using validation:
raw = request.body #Let's create the SHA1 signature #based on the request body JSON (raw) and our passphrase (key) hashed = hmac.new(key, raw, hashlib.sha1) validatedSignature = hashed.hexdigest() print 'validatedSignature', validatedSignature print 'X-Spark-Signature', request.headers.get('X-Spark-Signature') if validatedSignature == request.headers.get('X-Spark-Signature'): …RUN THE APP… else: print "Secret does not match, verboten!"
You can expand on all of the logic extensively, but for the basic use of a secret in a functional bot app, this covers what you need to know. If you have any questions, please contact firstname.lastname@example.org 24/7/365 and we’ll be happy to help!