Webhooks expliqués : signatures et tentatives

Backend2026-11-09TryQuickToolBox

Vous venez d'intégrer une passerelle de paiement ou un service CI/CD, et vous devez maintenant recevoir des événements en temps réel. Les webhooks sont la solution standard, mais ils comportent deux défis critiques : vérifier que la requête provient bien de l'expéditeur et garantir que les événements ne sont pas perdus si votre serveur est temporairement indisponible. Cet article explique comment implémenter des payloads signés et des mécanismes de nouvelle tentative pour construire un récepteur de webhooks robuste.

Que sont les webhooks ?

Un webhook est un callback HTTP : au lieu que votre application interroge une API pour obtenir des mises à jour, le service envoie une requête HTTP POST à une URL que vous fournissez chaque fois qu'un événement se produit. Ce modèle push réduit la latence et la charge serveur. Cependant, comme la requête provient d'un service externe, vous devez la traiter comme une entrée non fiable.

Pourquoi signer les payloads ?

Sans vérification, toute personne qui découvre votre point de terminaison de webhook pourrait envoyer de faux événements, déclenchant potentiellement des actions non autorisées. La signature des payloads avec un secret partagé vous permet de confirmer l'identité de l'expéditeur et de vous assurer que le payload n'a pas été altéré. La méthode la plus courante est HMAC (Hash-based Message Authentication Code) avec SHA-256.

Comment fonctionne la signature HMAC

L'expéditeur calcule un condensé HMAC du corps brut de la requête à l'aide d'une clé secrète et l'inclut dans un en-tête (par exemple, X-Signature). Votre serveur recalcule le HMAC avec le même secret et le compare à la signature reçue. S'ils correspondent, la requête est authentique.

// Exemple Node.js : vérification d'une signature de webhook
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(payload);
  const digest = hmac.digest('hex');
  // Utilisez timingSafeEqual pour éviter les attaques temporelles
  return crypto.timingSafeEqual(
    Buffer.from(digest, 'hex'),
    Buffer.from(signature, 'hex')
  );
}

Important : Utilisez toujours une fonction de comparaison à temps constant (comme timingSafeEqual) pour éviter de divulguer des informations via des différences de timing. De plus, calculez le HMAC sur le corps brut, et non sur le JSON analysé, car la re-sérialisation peut modifier la séquence d'octets.

Implémentation des nouvelles tentatives

Même avec les signatures, des problèmes réseau ou des erreurs serveur peuvent entraîner l'échec de la livraison du webhook. Un expéditeur fiable réessaiera les livraisons échouées, généralement avec un backoff exponentiel. En tant que récepteur, vous devez concevoir votre point de terminaison pour être idempotent et renvoyer les codes de statut appropriés.

Stratégie de nouvelle tentative du point de vue de l'expéditeur

Concevoir un récepteur idempotent

Étant donné que les nouvelles tentatives peuvent entraîner des livraisons en double, votre récepteur doit gérer le même événement plusieurs fois sans effets néfastes. Incluez un ID d'événement unique dans le payload (ou l'en-tête) et stockez les ID traités. Si un ID d'événement a déjà été traité, renvoyez immédiatement un 200 OK sans retraitement.

// Pseudocode pour une gestion idempotente des webhooks
function handleWebhook(event) {
  if (processedEvents.has(event.id)) {
    return { status: 200, body: 'Already processed' };
  }
  // Traitement de l'événement...
  processedEvents.add(event.id);
  return { status: 200, body: 'Success' };
}

Meilleures pratiques pour la sécurité et la fiabilité des webhooks

Comparaison : interrogation vs webhooks

AspectInterrogationWebhooks
LatenceDépend de l'intervalleQuasi temps réel
Charge serveurÉlevée (requêtes fréquentes)Faible (uniquement sur événements)
ComplexitéSimple à implémenterNécessite vérification de signature et gestion des nouvelles tentatives
FiabilitéVous contrôlez les nouvelles tentativesDépend de la politique de nouvelle tentative de l'expéditeur

FAQ

Comment vérifier une signature de webhook ?

Calculez un HMAC du corps brut de la requête à l'aide du secret partagé, puis comparez-le à la signature dans l'en-tête à l'aide d'une fonction de comparaison à temps constant.

Que doit renvoyer mon point de terminaison de webhook ?

Renvoyez un code de statut 2xx (par exemple, 200 OK) dès que vous avez reçu l'événement. Si vous renvoyez 4xx ou 5xx, l'expéditeur peut réessayer ou marquer la livraison comme échouée.

Puis-je utiliser des webhooks sans signatures ?

Ce n'est pas recommandé. Sans signatures, vous ne pouvez pas vérifier l'expéditeur, ce qui laisse votre point de terminaison vulnérable aux requêtes falsifiées. Utilisez toujours des signatures en production.

Lors du débogage des payloads de webhooks, le formatage JSON est essentiel. Utilisez notre formateur JSON pour imprimer et valider rapidement les données JSON entrantes.