JAVASCRIPT
Receiving and Validating Webhooks in Node.js
Implement a secure Node.js endpoint with Express to receive and validate incoming webhooks from services like Stripe or GitHub, ensuring data integrity using signature verification.
const express = require('express');
const crypto = require('crypto');
const app = express();
const PORT = process.env.PORT || 3001;
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET; // Store webhook secret securely
// Middleware to parse raw body for signature verification
app.use(express.json({ verify: (req, res, buf) => {
req.rawBody = buf.toString();
}}));
app.post('/webhook', (req, res) => {
const signature = req.headers['x-hub-signature-256'] || req.headers['stripe-signature']; // Example headers
if (!signature) {
return res.status(400).send('Webhook signature missing.');
}
const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
hmac.update(req.rawBody);
const digest = `sha256=${hmac.digest('hex')}`; // For GitHub style
// For Stripe, the signature verification is more complex, involving timestamps.
// This example assumes a simpler GitHub-like HMAC verification.
if (!crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature))) {
console.warn('Webhook signature mismatch. Request origin may be spoofed.');
return res.status(403).send('Webhook signature invalid.');
}
// Process the webhook payload
console.log('Received valid webhook:', req.body);
// Implement your business logic here, e.g., update database, send notifications
res.status(200).send('Webhook received and processed successfully.');
});
app.listen(PORT, () => {
console.log(`Webhook listener on port ${PORT}`);
});
How it works: This snippet provides a Node.js Express endpoint for receiving and securely validating webhooks. Many third-party services send webhooks to notify your application of events. Verifying the webhook's signature using a shared secret (HMAC) is crucial to ensure the request truly came from the expected source and hasn't been tampered with, preventing malicious or spoofed data injections. The `req.rawBody` is used for signature generation before `express.json()` parses it.