JAVASCRIPT
Secure Webhook Receiver with Signature Verification
Build a secure Node.js Express webhook endpoint that verifies incoming requests using a shared secret signature, preventing spoofing and ensuring data integrity.
const express = require('express');
const crypto = require('crypto');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;
// IMPORTANT: Use a strong, unique secret key for your webhook
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET || 'your_super_secret_key_here';
// Raw body needed for signature verification
app.use(bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf;
}
}));
// Middleware to verify webhook signature
function verifyWebhookSignature(req, res, next) {
const signature = req.headers['x-webhook-signature']; // Or 'stripe-signature', 'x-github-event', etc.
if (!signature) {
console.warn('Webhook received without signature.');
return res.status(401).send('Unauthorized: Signature missing.');
}
const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
// Ensure rawBody is available. For some webhooks, the signature is based on the JSON string itself.
// If not available, you might need to stringify req.body or handle buffer differently.
hmac.update(req.rawBody || JSON.stringify(req.body));
const digest = 'sha256=' + hmac.digest('hex'); // Adjust prefix based on webhook provider (e.g., 'v1=', 'sha256=')
if (digest !== signature) {
console.warn(`Invalid webhook signature. Expected: ${digest}, Got: ${signature}`);
return res.status(403).send('Forbidden: Invalid signature.');
}
console.log('Webhook signature verified successfully.');
next();
}
app.post('/webhook', verifyWebhookSignature, (req, res) => {
console.log('Received verified webhook payload:', req.body);
// Process the webhook payload here
// e.g., update database, trigger other services
res.status(200).send('Webhook received and processed.');
});
app.listen(port, () => {
console.log(`Webhook listener running at http://localhost:${port}`);
console.log('Remember to set WEBHOOK_SECRET environment variable in production!');
});
How it works: This Node.js Express snippet sets up a secure webhook receiver. It uses a `bodyParser` to access the raw request body, which is crucial for signature verification. The `verifyWebhookSignature` middleware calculates an HMAC signature using a shared secret and compares it with the signature provided in the request header (`x-webhook-signature`). This process ensures that the incoming webhook payload has not been tampered with and originates from a trusted source.