Webhooks verification examples
A collection of code snippets to help you verify webhook signatures
This article provides examples of how to verify webhook signatures in various languages and frameworks.
NodeJS
Let’s take a look at what authenticating Webhooks using signature verification looks like with NodeJS
Requirements
- Node.js >= 16
- Webhook configured to work with a local server
Launch a local server with verification
- Create 2 files
main.js
andpackage.json
. - Copy content from the code snippet below.
- Put your
Signing key
into thesecret
const. - Run
npm i
. - Run
npm start
.
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('node:crypto');
// App
const app = express();
const port = 1337;
const sigHeaderName = 'x-deel-signature';
const sigHashAlg = 'sha256';
const sigPrefix = 'POST';
const secret = 'your_webhook_signing_key';
//Get the raw body
//Validate payload
function validatePayload(req, res, next) {
if (req.get(sigHeaderName)) {
//Extract Signature header
const sig = Buffer.from(req.get(sigHeaderName) || '', 'utf8')
//Calculate HMAC
const hmac = crypto.createHmac(sigHashAlg, secret)
const digest = Buffer.from(hmac.update(sigPrefix + req.rawBody).digest('hex'), 'utf8');
//Compare HMACs
if (sig.length !== digest.length || !crypto.timingSafeEqual(digest, sig)) {
const message = `Request body digest (${digest}) did not match ${sigHeaderName} (${sig})`;
console.error(message);
return res.status(401).send({
message
});
} else {
return res.status(200).send({
message: `Webhook signature verification successful`
});
}
}
return next();
}
function post(req) {
console.log(JSON.stringify(req.body, null, 2));
}
app.use(bodyParser.json(
{
verify: (req, res, buf, encoding) => {
if (buf && buf.length) {
req.rawBody = buf.toString(encoding || 'utf8');
}
},
}
));
app.use(validatePayload);
app.post('/', post);
app.set('port', port);
app.listen(port, () => console.log(`Server running on localhost: ${port}`));
{
"name": "validate-webhook",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node main.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "~1.20.1",
"express": "~4.18.2"
}
}
Once the server is running, you can use the below cURL after replacing placeholder values to verify the signature.
curl --location 'http://localhost:$PORT' \
--header 'x-deel-signature: <header value you received>' \
--header 'Content-Type: application/json' \
--data-raw '<data you received without any modification>'
Updated about 17 hours ago