Consommateurs de Webhooks Idempotents avec Ruby on Rails pour les Événements Didit (FR)
Construire des consommateurs de webhooks robustes est essentiel pour un traitement fiable des données, surtout pour les événements en temps réel provenant de plateformes de vérification d'identité comme Didit.

Assurer l'Intégrité des DonnéesL'idempotence est cruciale pour traiter les événements webhook de manière fiable, en prévenant les actions en double et en maintenant un état cohérent dans votre application.
Exploiter les Signatures de WebhookVérifiez toujours les signatures de webhook pour confirmer l'authenticité et l'intégrité des requêtes entrantes, protégeant ainsi contre la falsification et l'usurpation d'identité.
Utiliser des Identifiants d'Événement UniquesStockez et vérifiez les identifiants d'événement uniques fournis dans les charges utiles des webhooks pour détecter et écarter efficacement les livraisons en double.
Le Système de Webhook Robuste de DiditDidit fournit des webhooks sécurisés et versionnés avec des signatures HMAC et des identifiants d'événement uniques, simplifiant l'implémentation de consommateurs idempotents et garantissant une livraison fiable des événements pour les flux de travail critiques de vérification d'identité.
Le Défi de l'Idempotence des Webhooks
Les webhooks sont un mécanisme puissant pour la communication en temps réel entre services, permettant à votre application de réagir instantanément aux événements se produisant dans un autre système. Cependant, la nature distribuée des webhooks signifie que les événements peuvent parfois être livrés plusieurs fois. Les problèmes de réseau, les délais d'attente ou les tentatives de réessai peuvent tous entraîner des charges utiles de webhook en double. Sans une gestion appropriée, ces doublons peuvent causer des problèmes importants dans votre application, tels que la création d'enregistrements en double, le déclenchement d'actions redondantes ou la corruption de données.
C'est là que l'idempotence devient critique. Une opération idempotente est une opération qui produit le même résultat qu'elle soit exécutée une seule fois ou plusieurs fois. Pour les consommateurs de webhook, cela signifie concevoir votre système pour traiter un événement donné une seule fois, même si la charge utile du webhook est reçue plusieurs fois. Lorsque l'on traite des données sensibles comme les résultats de vérification d'identité provenant de plateformes comme Didit, garantir l'idempotence n'est pas seulement une bonne pratique, c'est essentiel pour maintenir l'intégrité des données et la fiabilité du système.
Vérification des Signatures de Webhook pour la Sécurité et l'Authenticité
Avant de traiter toute charge utile de webhook, la première étape et la plus critique est de vérifier son authenticité. Cela garantit que le webhook provient réellement de l'expéditeur attendu (par exemple, Didit) et que son contenu n'a pas été altéré pendant le transit. Les webhooks de Didit, par exemple, incluent une signature HMAC dans les en-têtes de requête, générée à l'aide d'une clé secrète partagée.
Dans votre application Ruby on Rails, vous devrez récupérer la clé secrète partagée depuis votre compte Didit (à laquelle vous pouvez accéder via la console d'entreprise ou par programme à l'aide de l'API). Lorsqu'un webhook arrive, vous calculerez votre propre signature HMAC en utilisant le corps de la requête et votre clé secrète. Cette signature calculée est ensuite comparée à la signature fournie dans l'en-tête du webhook. Si elles ne correspondent pas, la requête doit être rejetée immédiatement.
class DiditWebhooksController < ApplicationController
skip_before_action :verify_authenticity_token
def create
# Récupérez la clé secrète partagée de vos variables d'environnement
secret = ENV['DIDIT_WEBHOOK_SECRET']
payload = request.body.read
signature = request.headers['X-Didit-Signature'] # Ou un nom d'en-tête similaire
unless verify_signature(payload, signature, secret)
head :unauthorized
return
end
# Traitez la charge utile du webhook après vérification
process_didit_event(JSON.parse(payload))
head :ok
end
private
def verify_signature(payload, signature, secret)
digest = OpenSSL::Digest.new('sha256')
hmac = OpenSSL::HMAC.hexdigest(digest, secret, payload)
ActiveSupport::SecurityUtils.secure_compare("sha256=#{hmac}", signature)
end
def process_didit_event(event_data)
# ... implémentation pour le traitement ...
end
end
Didit simplifie cela en fournissant une secret_shared_key dans le cadre de sa configuration de webhook, qui peut être récupérée via l'API ou renouvelée au besoin. Ce mécanisme sécurisé est fondamental pour tout flux de travail de vérification d'identité, où l'intégrité des résultats, tels que ceux de la vérification d'identité ou des contrôles de vivacité, est primordiale.
Implémentation de l'Idempotence avec des Identifiants d'Événement Uniques
Une fois que vous avez vérifié l'authenticité du webhook, l'étape suivante consiste à garantir l'idempotence. La plupart des systèmes de webhook bien conçus, y compris celui de Didit, fournissent un identifiant unique pour chaque événement. Cet ID est crucial pour détecter et prévenir le traitement en double. Pour les webhooks de Didit (en particulier la v3, qui est recommandée), chaque charge utile d'événement inclut un ID unique que vous pouvez utiliser à cette fin.
La stratégie consiste à stocker ces ID d'événement dans votre base de données et à les vérifier avant de les traiter. Un modèle courant implique la création d'un modèle EventLog ou WebhookEvent :
# db/migrate/YYYYMMDDHHMMSS_create_webhook_events.rb
class CreateWebhookEvents < ActiveRecord::Migration[7.x]
def change
create_table :webhook_events do |t|
t.string :event_id, null: false, index: { unique: true }
t.string :event_type
t.jsonb :payload
t.string :status, default: 'pending'
t.timestamps
end
end
end
Lorsqu'un webhook arrive :
- Extrayez l'
event_idunique de la charge utile. - Tentez de créer un nouvel enregistrement
WebhookEventavec cetevent_id. - Si la création échoue en raison d'une violation de contrainte unique (ce qui signifie que l'
event_idexiste déjà), vous savez qu'il s'agit d'un doublon et pouvez l'ignorer en toute sécurité ou le consigner comme tel. - Si la création réussit, procédez au traitement de l'événement, en marquant son statut en conséquence.
class DiditWebhooksController < ApplicationController
# ... (vérification de signature comme ci-dessus) ...
def create
# ... (vérification de signature) ...
event_data = JSON.parse(payload)
event_id = event_data['id'] # En supposant que 'id' est l'identifiant unique de l'événement de Didit
# Utilisez une transaction pour assurer l'atomicité
ActiveRecord::Base.transaction do
webhook_event = WebhookEvent.find_or_initialize_by(event_id: event_id)
if webhook_event.persisted? # S'il existe déjà, c'est un doublon
Rails.logger.info "Événement webhook en double reçu : #{event_id}"
head :ok
return
end
webhook_event.event_type = event_data['type']
webhook_event.payload = event_data
webhook_event.status = 'processing'
webhook_event.save!
# Traitez l'événement dans un job en arrière-plan pour les tâches de longue durée
DiditEventProcessorJob.perform_later(webhook_event.id)
head :ok
end
rescue ActiveRecord::RecordNotUnique # Gérer les conditions de concurrence pour event_id
Rails.logger.warn "Condition de concurrence détectée pour l'événement webhook : #{event_id}. Ignoré."
head :ok
rescue JSON::ParserError
head :bad_request
rescue => e
Rails.logger.error "Erreur lors du traitement du webhook : #{e.message}"
head :internal_server_error
end
end
Cette approche, combinée à des tâches en arrière-plan pour le traitement réel, garantit que votre point de terminaison de webhook répond rapidement, empêchant les nouvelles tentatives de l'expéditeur, tout en gérant de manière fiable les doublons.
Gestion des Conditions de Concurrence et des Transactions
Même avec un index unique, des conditions de concurrence peuvent survenir si deux webhooks identiques arrivent presque simultanément. Les deux pourraient tenter de créer un nouvel enregistrement WebhookEvent avant que le premier ne valide sa transaction. Pour atténuer cela :
- Utiliser des Transactions de Base de Données : Enveloppez la logique
find_or_initialize_byet la logique de traitement ultérieure dans une transaction de base de données. Cela garantit que toute l'opération réussit ou échoue, maintenant la cohérence des données. - Gérer
RecordNotUnique: Soyez prêt à intercepter les exceptionsActiveRecord::RecordNotUnique. Si cette exception se produit lors de la tentative de sauvegarde d'un nouveauWebhookEvent, cela signifie une condition de concurrence où un autre processus a déjà inséré l'événement, et vous pouvez le traiter en toute sécurité comme un doublon.
Pour les opérations qui modifient les données d'application principales, l'extension de la transaction pour couvrir ces modifications est cruciale, ou du moins s'assurer que le job en arrière-plan qui traite l'événement implémente également ses propres vérifications d'idempotence sur les données d'application qu'il modifie.
Comment Didit Aide
Didit est une plateforme d'identité native de l'IA, axée sur les développeurs, conçue avec la fiabilité et la sécurité à l'esprit, ce qui facilite la mise en œuvre de consommateurs de webhooks robustes. Notre architecture modulaire fournit des API claires et des webhooks sécurisés qui sont intrinsèquement conçus pour prendre en charge le traitement idempotent.
- Webhooks Sécurisés : Les webhooks de Didit fournissent de solides signatures HMAC (en utilisant une
secret_shared_keyque vous pouvez gérer et renouveler) pour garantir l'authenticité et l'intégrité de chaque événement. Cette première étape cruciale dans l'idempotence est intégrée. Vous pouvez même spécifier lawebhook_version(v3 recommandée) pour une structure de charge utile optimale. - Identifiants d'Événement Uniques : Chaque événement webhook Didit inclut un identifiant unique, ce qui simplifie l'implémentation de la logique de déduplication discutée ci-dessus.
- Rétention des Données Configurable : Avec Didit, vous contrôlez la durée de stockage des données de vérification. Vous pouvez définir des politiques de rétention des données de 1 mois à 10 ans, ou même null pour une durée illimitée, directement dans la console d'entreprise ou via l'API. Cela vous permet de respecter les exigences de conformité (comme le RGPD) tout en gérant votre empreinte de données. Cela est également lié à la façon dont votre consommateur de webhook pourrait stocker et gérer les journaux d'événements.
- KYC Core Gratuit et Conception Modulaire : Didit propose le KYC Core Gratuit, vous permettant de commencer à construire et à tester vos consommateurs de webhook sans frais initiaux. Notre conception modulaire signifie que vous pouvez facilement intégrer des produits de vérification d'identité spécifiques — comme la vérification d'identité pour les contrôles de documents, la vivacité passive et active pour la prévention de la fraude, ou l'estimation de l'âge pour la vérification de l'âge — et recevoir des mises à jour en temps réel via des webhooks.
En tirant parti du système de webhook robuste et sécurisé de Didit, les développeurs peuvent se concentrer davantage sur la logique centrale de leur application et moins sur les complexités de la sécurisation et de la déduplication des événements entrants, ce qui conduit à des flux de travail de vérification d'identité plus résilients et fiables.
Prêt à Commencer ?
Prêt à voir Didit en action ? Obtenez une démo gratuite dès aujourd'hui.
Commencez à vérifier les identités gratuitement avec le niveau gratuit de Didit.