Vérifier la signature d’un webhook

Mis à jour le 15 octobre 2026

Chaque appel porte l’en-tête Zean-Signature, de la forme « t=…,v1=… ». Vérifiez-le pour être sûr que l’appel vient bien de Zean.

  • t : l’heure de l’envoi, en secondes Unix.
  • v1 : la signature HMAC-SHA256 en hexadécimal, calculée avec le secret de signature sur le texte formé de t, d’un point et du corps brut de la requête.
  1. Lisez le corps brut de la requête, avant tout décodage JSON.
  2. Calculez la signature avec votre secret et comparez-la à v1 avec une comparaison à temps constant.
  3. Refusez un t trop ancien, par exemple de plus de 5 minutes. Chaque nouvel essai porte un t récent.

Exemple en Node.js

JSX
import crypto from 'node:crypto';
import express from 'express';

function isValidSignature(rawBody, header, secret) {
	const fields = Object.fromEntries(String(header).split(',').map(field => field.split('=')));
	const fresh = Math.abs(Date.now() / 1000 - Number(fields.t)) < 300;
	const expected = crypto.createHmac('sha256', secret).update(`${fields.t}.${rawBody}`).digest();
	const received = Buffer.from(fields.v1 ?? '', 'hex');
	return fresh && received.length === expected.length && crypto.timingSafeEqual(received, expected);
}

app.post('/zean/webhook', express.raw({ type: 'application/json' }), (req, res) => {
	if (!isValidSignature(req.body, req.headers['zean-signature'], process.env.ZEAN_WEBHOOK_SECRET)) {
		return res.sendStatus(401);
	}
	const event = JSON.parse(req.body);
	console.log(event.type, event.data.conversationId);
	res.sendStatus(200);
});

Le secret de signature se trouve dans Paramètres de l’App > Développeurs. Après l’avoir régénéré, mettez à jour votre serveur tout de suite : les appels suivants, nouveaux essais compris, sont signés avec le nouveau secret.

Besoin d'aide ?

Notre équipe vous répond dans le chat, en français ou en anglais.