The API reference provides a sample for webhook validation in different programming languages like node.js, which can be found here.
For those using express.js, you can kickstart with the following code template:
const express = require('express');
const crypto = require('crypto');
// Initiate express
const app = express();
// Configure raw bodyparser to read webhook post
const bodyParserRaw = require('body-parser').raw({
type: '*/*',
});
function webhookValidator (req, res, next) {
// Extract header signature from webhook request
const givenSignature = req.headers['x-kc-signature'];
// Throw error if missing
if (!givenSignature) {
console.log('Missing signature');
return res.status(409).json({
error: 'Missing signature'
});
}
// Create HMAC from raw request body
let hmac = crypto.createHmac('sha256', [your-webhook-secret-key]);
hmac.write(req.body);
hmac.end();
// Get base64 hash from HMAC
let hash = hmac.read().toString('base64');
// Check validity using timingSafeEqual
let webhookValid = false;
try {
webhookValid = crypto.timingSafeEqual(Buffer.from(givenSignature, 'base64'), Buffer.from(hash, 'base64'));
} catch (e) {
webhookValid = false
}
// Return validity
if (webhookValid) {
return next();
} else {
console.log('Invalid signature');
return res.status(409).json({
error: 'Invalid signature'
});
}
}
// Create route and include bodyparser and validator
app.post('/webhook', bodyParserRaw, webhookValidator, ( req, res, next ) => {
// If this point is reached, the HMAC is valid
console.log('webhook is valid');
});
UPDATE
To easily validate webhook notifications and their signatures, consider using the Kontent webhook helper library. This library can be accessed as an npm package @kentico/kontent-webhook-helper, offering assistance in avoiding common hash calculation issues.