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.

Need help integrating this into your project?

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

Hire DigitalCodeLabs