Tradotta dall'inglese. In caso di differenze fa fede la pagina in inglese. Leggi in inglese

Verifica le firme

Dimostra che un webhook arriva davvero da Nembol, con verificatori pronti da copiare in quattro linguaggi.

Ogni consegna contiene:

X-Nembol-Signature: t=1784900412,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
  • t: timestamp Unix del tentativo di consegna.
  • v1: HMAC-SHA256, calcolato con il signing secret del tuo endpoint sulla stringa "<t>.<raw_body>". Durante una finestra di rotazione del secret potresti vedere due voci v1=. Accetta se almeno una corrisponde.

Passi di verifica: (1) leggi il body grezzo della richiesta, prima di qualsiasi parsing JSON o trasformazione da parte di un middleware; (2) calcola l'HMAC atteso; (3) confronta in tempo costante; (4) rifiuta se |now − t| supera i 5 minuti (protezione dai replay).

import crypto from 'node:crypto';

// Express: app.post('/webhook', express.raw({ type: 'application/json' }), handler)
export function verifyNembolSignature(rawBody, signatureHeader, secret) {
  const parts = Object.fromEntries(
    signatureHeader.split(',').map((kv) => kv.split('=', 2)),
  );
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${t}.${rawBody}`)
    .digest('hex');

  return signatureHeader
    .split(',')
    .filter((kv) => kv.startsWith('v1='))
    .some((kv) => {
      const candidate = Buffer.from(kv.slice(3), 'hex');
      const exp = Buffer.from(expected, 'hex');
      return candidate.length === exp.length && crypto.timingSafeEqual(candidate, exp);
    });
}

L'errore classico: verificare su un body JSON riserializzato. Il JSON che il tuo framework analizza e poi riconverte in stringa non sarà identico byte per byte a quello che Nembol ha inviato, e la firma non corrisponderà. Conserva sempre i byte grezzi.

Ultimo aggiornamento il 20 ottobre 2026

Serve aiuto?

Scrivici e ti risponde una persona, di solito entro un giorno lavorativo.