Checking X-Loop-Signature Header

Example Express Webhook Endpoint

const assert = require('assert');
const crypto = require('crypto');
const express = require('express');

const app = express();

// get raw payload buffer first before other middleware can act on it
app.use(express.raw({
    type: '*/*',
    verify: function(req, _res, buf) {
        if (Buffer.isBuffer(buf)) {
            req.buffer = buf;
        }
    },
}));
app.use(express.json()) // for parsing application/json

app.post('/endpoint', (req, res) => {
  const jsonPayload = JSON.stringify(req.body);

  const hmac = crypto.createHmac('sha256', '<SECRET>') // substitute secret
        .update(req.buffer, 'utf-8')
        .digest('base64');

  const signature = req.get('X-Loop-Signature');

  assert.equal(hmac, signature); // validate match

  res.json({ signature, jsonPayload });
});


app.listen(3000, () => console.log('ready'));

When receiving a webhook from Loop, use the secret provided for the webhook to create a sha256 HMAC with the stringified request body encoded as a base64 value. You can then compare that HMAC to the value that was provided in the X-Loop-Signature header of the request, to ensure that the values match. This will ensure that the request came from Loop.


Did this page help you?