Saltar al contenido principal
Didit recauda 7,5M $ para construir la infraestructura para identidad y fraude
Didit
Volver al blog
Blog · 6 de marzo de 2026

Consumidores Idempotentes de Webhooks en Ruby on Rails para Eventos Didit (ES)

Construir consumidores de webhooks robustos es crucial para un procesamiento de datos fiable, especialmente para eventos en tiempo real de plataformas de verificación de identidad como Didit.

Por DiditActualizado el
idempotent-webhook-consumers-ruby-rails-didit-events.png

Asegurando la Integridad de los DatosLa idempotencia es vital para procesar eventos de webhook de forma fiable, previniendo acciones duplicadas y manteniendo un estado consistente en tu aplicación.

Aprovechando las Firmas de WebhookSiempre verifica las firmas de webhook para confirmar la autenticidad e integridad de las solicitudes entrantes, protegiéndote contra manipulaciones y suplantaciones.

Utilizando IDs de Evento ÚnicosAlmacena y verifica los IDs de evento únicos proporcionados en las cargas útiles de los webhooks para detectar y descartar entregas duplicadas de manera efectiva.

El Robusto Sistema de Webhooks de DiditDidit proporciona webhooks seguros y versionados con firmas HMAC e IDs de evento únicos, simplificando la implementación de consumidores idempotentes y asegurando la entrega fiable de eventos para flujos de trabajo críticos de verificación de identidad.

El Desafío de la Idempotencia de Webhooks

Los webhooks son un mecanismo potente para la comunicación en tiempo real entre servicios, permitiendo que tu aplicación reaccione instantáneamente a eventos que ocurren en otro sistema. Sin embargo, la naturaleza distribuida de los webhooks significa que los eventos a veces pueden ser entregados múltiples veces. Fallas en la red, tiempos de espera o reintentos pueden llevar a cargas útiles de webhook duplicadas. Sin un manejo adecuado, estos duplicados pueden causar problemas significativos en tu aplicación, como la creación de registros duplicados, el desencadenamiento de acciones redundantes o la corrupción de datos.

Aquí es donde la idempotencia se vuelve crítica. Una operación idempotente es aquella que produce el mismo resultado si se ejecuta una o varias veces. Para los consumidores de webhooks, esto significa diseñar tu sistema para procesar un evento dado solo una vez, incluso si la carga útil del webhook se recibe varias veces. Cuando se trata de datos sensibles como los resultados de verificación de identidad de plataformas como Didit, asegurar la idempotencia no es solo una buena práctica, es esencial para mantener la integridad de los datos y la fiabilidad del sistema.

Verificación de Firmas de Webhook para Seguridad y Autenticidad

Antes de procesar cualquier carga útil de webhook, el primer y más crítico paso es verificar su autenticidad. Esto asegura que el webhook realmente se originó del remitente esperado (por ejemplo, Didit) y que su contenido no ha sido manipulado durante el tránsito. Los webhooks de Didit, por ejemplo, incluyen una firma HMAC en los encabezados de la solicitud, generada utilizando una clave secreta compartida.

En tu aplicación Ruby on Rails, necesitarás recuperar la clave secreta compartida de tu cuenta Didit (a la que puedes acceder a través de la Consola de Negocios o programáticamente usando la API). Cuando llega un webhook, calcularás tu propia firma HMAC utilizando el cuerpo de la solicitud y tu clave secreta. Esta firma calculada se compara luego con la firma proporcionada en el encabezado del webhook. Si no coinciden, la solicitud debe ser rechazada inmediatamente.


class DiditWebhooksController < ApplicationController
  skip_before_action :verify_authenticity_token

  def create
    # Recupera la clave secreta compartida de tus variables de entorno
    secret = ENV['DIDIT_WEBHOOK_SECRET']
    payload = request.body.read
    signature = request.headers['X-Didit-Signature'] # O nombre de encabezado similar

    unless verify_signature(payload, signature, secret)
      head :unauthorized
      return
    end

    # Procesa la carga útil del webhook después de la verificación
    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)
    # ... implementación para el procesamiento ...
  end
end

Didit simplifica esto al proporcionar una secret_shared_key como parte de su configuración de webhook, que se puede recuperar a través de la API o rotar según sea necesario. Este mecanismo seguro es fundamental para cualquier flujo de trabajo de verificación de identidad, donde la integridad de los resultados, como los de Verificación de ID o Verificación de Vida, es primordial.

Implementación de Idempotencia con Identificadores Únicos de Evento

Una vez que hayas verificado la autenticidad del webhook, el siguiente paso es asegurar la idempotencia. La mayoría de los sistemas de webhook bien diseñados, incluido el de Didit, proporcionan un identificador único para cada evento. Este ID es crucial para detectar y prevenir el procesamiento duplicado. Para los webhooks de Didit (especialmente la v3, que es la recomendada), cada carga útil de evento incluye un ID único que puedes usar para este propósito.

La estrategia es almacenar estos IDs de evento en tu base de datos y verificarlos antes de procesar. Un patrón común implica crear un modelo EventLog o 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

Cuando llega un webhook:

  1. Extrae el event_id único de la carga útil.
  2. Intenta crear un nuevo registro WebhookEvent con este event_id.
  3. Si la creación falla debido a una violación de restricción única (lo que significa que el event_id ya existe), entonces sabes que es un duplicado y puedes ignorarlo de forma segura o registrarlo como tal.
  4. Si la creación es exitosa, procede a procesar el evento, marcando su estado en consecuencia.

class DiditWebhooksController < ApplicationController
  # ... (verificación de firma como se indicó anteriormente) ...

  def create
    # ... (verificación de firma) ...

    event_data = JSON.parse(payload)
    event_id = event_data['id'] # Asumiendo que 'id' es el identificador único del evento de Didit

    # Usa una transacción para asegurar la atomicidad
    ActiveRecord::Base.transaction do
      webhook_event = WebhookEvent.find_or_initialize_by(event_id: event_id)

      if webhook_event.persisted? # Si ya existe, es un duplicado
        Rails.logger.info "Evento de webhook duplicado recibido: #{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!

      # Procesa el evento en un trabajo en segundo plano para tareas de larga duración
      DiditEventProcessorJob.perform_later(webhook_event.id)
      head :ok
    end
  rescue ActiveRecord::RecordNotUnique # Maneja condiciones de carrera para event_id
    Rails.logger.warn "Condición de carrera detectada para evento de webhook: #{event_id}. Ignorando."
    head :ok
  rescue JSON::ParserError
    head :bad_request
  rescue => e
    Rails.logger.error "Error al procesar el webhook: #{e.message}"
    head :internal_server_error
  end
end

Este enfoque, combinado con trabajos en segundo plano para el procesamiento real, asegura que tu punto final de webhook responda rápidamente, evitando reintentos del remitente, mientras maneja de manera fiable los duplicados.

Manejo de Condiciones de Carrera y Transacciones

Incluso con un índice único, pueden ocurrir condiciones de carrera si dos webhooks idénticos llegan casi simultáneamente. Ambos podrían intentar crear un nuevo registro WebhookEvent antes de que el primero confirme su transacción. Para mitigar esto:

  • Usa Transacciones de Base de Datos: Envuelve la lógica de find_or_initialize_by y el procesamiento posterior dentro de una transacción de base de datos. Esto asegura que toda la operación tenga éxito o falle, manteniendo la consistencia de los datos.
  • Maneja RecordNotUnique: Prepárate para capturar excepciones ActiveRecord::RecordNotUnique. Si esta excepción ocurre al intentar guardar un nuevo WebhookEvent, significa una condición de carrera donde otro proceso ya ha insertado el evento, y puedes tratarlo de forma segura como un duplicado.

Para operaciones que modifican datos centrales de la aplicación, extender la transacción para cubrir esos cambios es crucial, o al menos asegurar que el trabajo en segundo plano que procesa el evento también implemente sus propias comprobaciones de idempotencia en los datos de la aplicación que modifica.

Cómo Ayuda Didit

Didit es una plataforma de identidad nativa de IA y centrada en el desarrollador, diseñada con fiabilidad y seguridad en mente, lo que facilita la implementación de consumidores de webhooks robustos. Nuestra arquitectura modular proporciona APIs limpias y webhooks seguros que están inherentemente diseñados para soportar el procesamiento idempotente.

  • Webhooks Seguros: Los webhooks de Didit proporcionan firmas HMAC fuertes (utilizando una secret_shared_key que puedes gestionar y rotar) para asegurar la autenticidad e integridad de cada evento. Este primer paso crucial en la idempotencia está incorporado. Incluso puedes especificar la webhook_version (v3 recomendada) para una estructura de carga útil óptima.
  • Identificadores Únicos de Evento: Cada evento de webhook de Didit incluye un identificador único, lo que facilita la implementación de la lógica de deduplicación discutida anteriormente.
  • Retención de Datos Configurable: Con Didit, tú controlas cuánto tiempo se almacenan los datos de verificación. Puedes establecer políticas de retención de datos desde 1 mes hasta 10 años, o incluso nulo para ilimitado, directamente en la Consola de Negocios o a través de la API. Esto te permite cumplir con los requisitos de cumplimiento (como GDPR) mientras gestionas tu huella de datos. Esto también se relaciona con cómo tu consumidor de webhook podría almacenar y gestionar registros de eventos.
  • KYC Básico Gratuito y Diseño Modular: Didit ofrece KYC Básico Gratuito, lo que te permite comenzar a construir y probar tus consumidores de webhook sin costos iniciales. Nuestro diseño modular significa que puedes integrar fácilmente productos específicos de verificación de identidad, como Verificación de ID para comprobaciones de documentos, Vitalidad Pasiva y Activa para prevención de fraude, o Estimación de Edad para verificación de edad, y recibir actualizaciones en tiempo real a través de webhooks.

Al aprovechar el sistema de webhooks robusto y seguro de Didit, los desarrolladores pueden centrarse más en la lógica central de su aplicación y menos en las complejidades de asegurar y deduplicar los eventos entrantes, lo que lleva a flujos de trabajo de verificación de identidad más resilientes y confiables.

¿Listo para Empezar?

¿Listo para ver Didit en acción? Obtén una demostración gratuita hoy.

Comienza a verificar identidades gratis con el nivel gratuito de Didit.

Infraestructura para identidad y fraude.

Una API para KYC, KYB, Monitoreo de Transacciones y Detección de Fraude en Wallets. Intégrala en 5 minutos.

Pide a una IA que resuma esta página
Consumidores Idempotentes de Webhooks en Rails con Didit.