JAVASCRIPT

Securely Processing Webhook Payloads in Node.js

Learn how to set up an Express.js endpoint to receive and securely verify webhook payloads from third-party services using HMAC signatures for integrity.

// Install: npm install express body-parser crypto
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');

const app = express();
const WEBHOOK_SECRET = 'your_super_secret_webhook_key'; // Replace with a strong, unique secret

// Raw body parser for signature verification
app.use(bodyParser.json({
  verify: (req, res, buf) => {
    req.rawBody = buf; // Store raw body for signature verification
  }
}));

app.post('/webhook-endpoint', (req, res) => {
  const signature = req.headers['x-hub-signature-256'] || req.headers['x-signature']; // Example header names

  if (!signature) {
    console.error('Webhook received without signature');
    return res.status(401).send('Unauthorized: Signature missing');
  }

  // Calculate HMAC-SHA256 signature
  const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET)
                     .update(req.rawBody)
                     .digest('hex');

  // Compare the calculated signature with the one from the header
  const receivedSignature = signature.replace('sha256=', ''); // Remove prefix if present

  if (!crypto.timingSafeEqual(Buffer.from(hmac, 'hex'), Buffer.from(receivedSignature, 'hex'))) {
    console.error('Webhook signature mismatch:', { expected: hmac, received: receivedSignature });
    return res.status(403).send('Forbidden: Invalid signature');
  }

  // Signature is valid, process the webhook payload
  console.log('Webhook payload received and verified:', req.body);
  // Example: Respond to the webhook sender
  res.status(200).send('Webhook received successfully');

  // Add your business logic here, e.g., update a database, trigger another service
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Webhook server listening on port ${PORT}`);
});
How it works: This Node.js snippet demonstrates how to create an Express.js endpoint to receive and validate webhooks. Many services send webhooks with a signature (HMAC) in the request header, allowing you to verify that the payload genuinely originated from the service and hasn't been tampered with. The code uses `body-parser` to get the raw request body, then calculates an HMAC-SHA256 signature using a shared secret and compares it with the one provided in the `x-hub-signature-256` header, ensuring message integrity and authenticity before processing the data.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs