Naar de inhoud

Webhook: handtekening controleren

Naslag voor webbouwers. Controleer met HMAC-SHA256 en het signing secret dat een webhookbericht echt van meetpiloot komt en niet oud is.

PlusVoor ontwikkelaars1 min lezen
Op deze pagina1
  1. Voorbeeld in Node.js (Express)
Beschikbaar in Plus.

Elk bericht draagt de header X-Meetpiloot-Signature: sha256= gevolgd door een HMAC-SHA256 over de exacte body, met je signing secret als sleutel. Bereken die opnieuw over de ruwe body en vergelijk met een timing-veilige functie.

X-Meetpiloot-Timestamp bevat het verzendmoment in ISO-8601. Weiger berichten die ouder zijn dan een paar minuten, zodat een onderschept bericht niet later opnieuw kan worden afgespeeld.

Voorbeeld in Node.js (Express)

JavaScript
const crypto = require('crypto');

function isFromMeetpiloot(rawBody, header, secret) {
  const expected =
    'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  const a = Buffer.from(header || '');
  const b = Buffer.from(expected);
  // timingSafeEqual werpt een fout bij ongelijke lengtes, dus eerst controleren.
  if (a.length !== b.length) return false;
  return crypto.timingSafeEqual(a, b);
}

// Let op express.raw(): de handtekening gaat over de exacte bytes die we stuurden,
// dus controleer voordat je de JSON parset of opnieuw serialiseert.
app.post('/meetpiloot', express.raw({ type: 'application/json' }), (req, res) => {
  if (!isFromMeetpiloot(req.body, req.get('X-Meetpiloot-Signature'), process.env.MP_SECRET)) {
    return res.sendStatus(401);
  }
  const payload = JSON.parse(req.body.toString('utf8'));
  if (payload.event === 'lead.test') return res.sendStatus(200); // oefening, geen echte lead
  res.sendStatus(200);   // eerst antwoorden...
  forwardToCrm(payload); // ...dan het trage werk
});

Maak je een nieuw secret aan in je dashboard, dan is het oude direct ongeldig. Zet het nieuwe secret dus meteen ook in het ontvangende systeem.

Kom je er niet uit?

Mail ons of open een ticket vanuit je dashboard. Antwoord binnen 1 tot 2 werkdagen.