Une URL de réception publique peut recevoir des requêtes de n'importe qui. Un attaquant peut envoyer un événement fabriqué à cette URL, la requête doit donc être authentifiée avant de déclencher un traitement.
Bird utilise le schéma de signature Standard Webhooks. Il authentifie l'identifiant de l'événement et l'heure de la tentative en même temps que le corps, si bien que modifier l'un d'entre eux invalide la signature.
Que signe Bird ?
Bird signe l'identifiant de l'événement, l'horodatage de la tentative de livraison et le corps brut de la requête, joints par des points.
Conservez le corps de la requête intact jusqu'à la vérification de la signature. Analyser puis resérialiser JSON peut modifier les octets que Bird a signés.
| En-tête | Contenu |
|---|---|
webhook-id | L'identifiant de l'événement, réutilisé d'une tentative et d'un rejeu à l'autre. |
webhook-timestamp | L'heure de la tentative sous forme d'horodatage Unix en secondes. |
webhook-signature | Une ou plusieurs signatures, séparées par des espaces. Chacune commence par v1,. |
Convertissez l'horodatage depuis les secondes avant de le comparer à une horloge qui rapporte des millisecondes.
Retirez le préfixe whsec_ du secret de votre endpoint et décodez le reste en base64 pour récupérer les octets de la clé.
Joignez l'identifiant, l'horodatage et le corps intact avec des points. Calculez un HMAC-SHA256 sur cette chaîne avec la clé décodée. Comparez le résultat avec chaque signature fournie au moyen d'une comparaison en temps constant, dont la durée d'exécution ne révèle pas quels octets correspondent.
Pourquoi ma signature ne correspond-elle jamais ?
Un secret incorrect ou un corps de requête modifié peut faire échouer chaque vérification de signature.
Les frameworks web analysent souvent JSON avant l'exécution de votre handler. Resérialiser cet objet peut modifier les espaces, l'ordre des clés ou le format des nombres. Le JSON obtenu peut avoir la même signification tout en produisant une signature différente.
Configurez cette route pour conserver le corps brut de la requête. Vérifiez que le secret appartient bien à cet endpoint, surtout après un déploiement ou une rotation.
Que doit rejeter mon handler ?
Rejetez une requête lorsqu'aucune signature ne correspond ou que l'horodatage signé se situe en dehors de la fenêtre de temps autorisée.
Essayez chaque signature dans webhook-signature. Pendant une rotation de secret, une livraison porte des signatures provenant de plusieurs secrets valides. Accepter toute signature correspondante permet aux récepteurs utilisant l'un ou l'autre secret de continuer à fonctionner.
Utilisez une tolérance de cinq minutes de chaque côté de votre horloge. Une requête capturée dix minutes plus tôt échoue alors, même si sa signature est inchangée. Maintenez l'horloge de votre serveur à l'heure pour ne pas rejeter des livraisons légitimes.
Comparez webhook-id aux événements que vous avez déjà stockés. Un doublon reconnu doit recevoir un succès sans répéter son traitement, car réessayer la même livraison n'ajoute aucun nouvel événement.
Que se passe-t-il si je rejette une livraison ?
Bird réessaie une livraison qui reçoit une réponse d'erreur ou aucune réponse avant son délai d'expiration.
Une réponse 400, par exemple, enregistre le rejet et laisse la livraison éligible à une nouvelle tentative. Toutes les réponses non-2xx suivent la politique de réessai. Le code vous aide à diagnostiquer l'échec dans vos journaux.
Le calendrier s'étend sur environ 27,5 heures avant ajustements, ce qui vous laisse le temps de corriger un secret incorrect. Réessais de webhooks échoués décrit le calendrier et la marche à suivre pour rejouer les événements manqués.
Ne renvoyez 2xx qu'après avoir vérifié et stocké l'événement en toute sécurité, ou reconnu un doublon déjà stocké. Bird ignore les livraisons réussies pendant un rejeu, donc acquitter une requête non vérifiée empêche la récupération par ce mécanisme.
Dois-je implémenter la vérification moi-même ?
Vous n'avez pas besoin d'implémenter la vérification vous-même si vous utilisez webhooks.unwrap dans un Bird SDK. Transmettez-lui le corps brut et les en-têtes de la requête.
Le helper vérifie la signature et l'horodatage avant de renvoyer l'événement décodé. Votre application déduplique tout de même par webhook-id, car c'est elle qui détient le registre des traitements effectués.
Une bibliothèque de vérification Standard Webhooks compatible peut effectuer les mêmes contrôles. Le guide des webhooks contient des exemples et une implémentation manuelle.
En bref
Vérifiez les octets originaux.
Analyser puis resérialiser JSON peut modifier les octets que Bird a signés. Conservez le corps brut de la requête pour la vérification.
Contrôlez aussi l'horodatage.
Une tolérance de cinq minutes sur l'horodatage limite la réutilisation de requêtes capturées. Dédupliquez les événements stockés par webhook-id séparément.
Essayez chaque signature fournie.
La rotation crée des signatures qui se chevauchent. Une correspondance avec n'importe quelle signature valide permet au déploiement de continuer.
N'acquittez que les événements vérifiés et stockés.
Bird réessaie les réponses non-2xx et ignore les livraisons réussies pendant un rejeu. Renvoyez un succès pour les doublons déjà stockés sans répéter leur traitement.