Consumidores Idempotentes de Webhooks no Ruby on Rails para Eventos Didit (PT-BR)
Construir consumidores de webhook robustos é essencial para o processamento confiável de dados, especialmente para eventos em tempo real de plataformas de verificação de identidade como a Didit.

Garantindo a Integridade dos DadosA idempotência é vital para processar eventos de webhook de forma confiável, prevenindo ações duplicadas e mantendo um estado consistente em sua aplicação.
Aproveitando Assinaturas de WebhookSempre verifique as assinaturas de webhook para confirmar a autenticidade e integridade das requisições recebidas, protegendo contra adulterações e falsificações.
Utilizando IDs de Evento ÚnicosArmazene e verifique os IDs de evento únicos fornecidos nos payloads de webhook para detectar e descartar entregas duplicadas de forma eficaz.
O Sistema Robusto de Webhooks da DiditA Didit oferece webhooks seguros e versionados com assinaturas HMAC e IDs de evento únicos, simplificando a implementação de consumidores idempotentes e garantindo a entrega confiável de eventos para fluxos de trabalho críticos de verificação de identidade.
O Desafio da Idempotência de Webhooks
Webhooks são um mecanismo poderoso para comunicação em tempo real entre serviços, permitindo que sua aplicação reaja instantaneamente a eventos que ocorrem em outro sistema. No entanto, a natureza distribuída dos webhooks significa que os eventos podem, às vezes, ser entregues várias vezes. Falhas de rede, timeouts ou retentativas podem levar a payloads de webhook duplicados. Sem o tratamento adequado, essas duplicatas podem causar problemas significativos em sua aplicação, como a criação de registros duplicados, o disparo de ações redundantes ou a corrupção de dados.
É aqui que a idempotência se torna crítica. Uma operação idempotente é aquela que produz o mesmo resultado, seja executada uma ou várias vezes. Para consumidores de webhook, isso significa projetar seu sistema para processar um determinado evento apenas uma vez, mesmo que o payload do webhook seja recebido várias vezes. Ao lidar com dados sensíveis, como resultados de verificação de identidade de plataformas como a Didit, garantir a idempotência não é apenas uma boa prática — é essencial para manter a integridade dos dados e a confiabilidade do sistema.
Verificando Assinaturas de Webhook para Segurança e Autenticidade
Antes de processar qualquer payload de webhook, o primeiro e mais crítico passo é verificar sua autenticidade. Isso garante que o webhook realmente se originou do remetente esperado (por exemplo, Didit) e que seu conteúdo não foi adulterado em trânsito. Os webhooks da Didit, por exemplo, incluem uma assinatura HMAC nos cabeçalhos da requisição, gerada usando uma chave secreta compartilhada.
Em sua aplicação Ruby on Rails, você precisará recuperar a chave secreta compartilhada de sua conta Didit (que pode ser acessada via Business Console ou programaticamente usando a API). Quando um webhook chega, você calculará sua própria assinatura HMAC usando o corpo da requisição e sua chave secreta. Esta assinatura calculada é então comparada à assinatura fornecida no cabeçalho do webhook. Se elas não corresponderem, a requisição deve ser rejeitada imediatamente.
class DiditWebhooksController < ApplicationController
skip_before_action :verify_authenticity_token
def create
# Recupera a chave secreta compartilhada das suas variáveis de ambiente
secret = ENV['DIDIT_WEBHOOK_SECRET']
payload = request.body.read
signature = request.headers['X-Didit-Signature'] # Ou nome de cabeçalho similar
unless verify_signature(payload, signature, secret)
head :unauthorized
return
end
# Processa o payload do webhook após a verificação
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)
# ... implementação para processamento ...
end
end
A Didit simplifica isso fornecendo uma secret_shared_key como parte de sua configuração de webhook, que pode ser recuperada via API ou rotacionada conforme necessário. Este mecanismo seguro é fundamental para qualquer fluxo de trabalho de verificação de identidade, onde a integridade dos resultados, como os de Verificação de ID ou verificações de Liveness, é primordial.
Implementando Idempotência com Identificadores de Evento Únicos
Depois de verificar a autenticidade do webhook, o próximo passo é garantir a idempotência. A maioria dos sistemas de webhook bem projetados, incluindo o da Didit, fornece um identificador único para cada evento. Este ID é crucial para detectar e prevenir o processamento duplicado. Para os webhooks da Didit (especialmente a v3, que é recomendada), cada payload de evento inclui um ID único que você pode usar para essa finalidade.
A estratégia é armazenar esses IDs de evento em seu banco de dados e verificá-los antes do processamento. Um padrão comum envolve a criação de um modelo 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
Quando um webhook chega:
- Extraia o
event_idúnico do payload. - Tente criar um novo registro
WebhookEventcom esteevent_id. - Se a criação falhar devido a uma violação de restrição de unicidade (o que significa que o
event_idjá existe), você sabe que é uma duplicata e pode ignorá-la com segurança ou registrá-la como tal. - Se a criação for bem-sucedida, prossiga para processar o evento, marcando seu status de acordo.
class DiditWebhooksController < ApplicationController
# ... (verificação de assinatura como acima) ...
def create
# ... (verificação de assinatura) ...
event_data = JSON.parse(payload)
event_id = event_data['id'] # Assumindo que 'id' é o identificador de evento único da Didit
# Use uma transação para garantir atomicidade
ActiveRecord::Base.transaction do
webhook_event = WebhookEvent.find_or_initialize_by(event_id: event_id)
if webhook_event.persisted? # Se já existe, é uma duplicata
Rails.logger.info "Evento de webhook duplicado recebido: #{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!
# Processa o evento em um job em segundo plano para tarefas de longa duração
DiditEventProcessorJob.perform_later(webhook_event.id)
head :ok
end
rescue ActiveRecord::RecordNotUnique # Lida com condições de corrida para event_id
Rails.logger.warn "Condição de corrida detectada para evento de webhook: #{event_id}. Ignorando."
head :ok
rescue JSON::ParserError
head :bad_request
rescue => e
Rails.logger.error "Erro ao processar webhook: #{e.message}"
head :internal_server_error
end
end
Essa abordagem, combinada com jobs em segundo plano para o processamento real, garante que seu endpoint de webhook responda rapidamente, prevenindo retentativas do remetente, enquanto lida de forma confiável com duplicatas.
Lidando com Condições de Corrida e Transações
Mesmo com um índice exclusivo, condições de corrida podem ocorrer se dois webhooks idênticos chegarem quase simultaneamente. Ambos podem tentar criar um novo registro WebhookEvent antes que o primeiro finalize sua transação. Para mitigar isso:
- Use Transações de Banco de Dados: Envolva a lógica
find_or_initialize_bye o processamento subsequente dentro de uma transação de banco de dados. Isso garante que toda a operação seja bem-sucedida ou falhe, mantendo a consistência dos dados. - Lide com
RecordNotUnique: Esteja preparado para capturar exceçõesActiveRecord::RecordNotUnique. Se essa exceção ocorrer ao tentar salvar um novoWebhookEvent, isso significa uma condição de corrida onde outro processo já inseriu o evento, e você pode tratá-lo com segurança como uma duplicata.
Para operações que modificam dados centrais da aplicação, estender a transação para cobrir essas alterações é crucial, ou pelo menos garantir que o job em segundo plano que processa o evento também implemente suas próprias verificações de idempotência nos dados da aplicação que ele modifica.
Como a Didit Ajuda
A Didit é uma plataforma de identidade nativa de IA e focada em desenvolvedores, projetada com confiabilidade e segurança em mente, facilitando a implementação de consumidores de webhook robustos. Nossa arquitetura modular oferece APIs limpas e webhooks seguros que são inerentemente projetados para suportar o processamento idempotente.
- Webhooks Seguros: Os webhooks da Didit fornecem fortes assinaturas HMAC (usando uma
secret_shared_keyque você pode gerenciar e rotacionar) para garantir a autenticidade e integridade de cada evento. Este primeiro passo crucial na idempotência é integrado. Você pode até especificar awebhook_version(v3 recomendada) para uma estrutura de payload ideal. - Identificadores de Evento Únicos: Cada evento de webhook da Didit inclui um identificador único, tornando simples a implementação da lógica de deduplicação discutida acima.
- Retenção de Dados Configurável: Com a Didit, você controla por quanto tempo os dados de verificação são armazenados. Você pode definir políticas de retenção de dados de 1 mês a 10 anos, ou até nulo para ilimitado, diretamente no Business Console ou via API. Isso permite que você cumpra os requisitos de conformidade (como o GDPR) enquanto gerencia sua pegada de dados. Isso também se relaciona com a forma como seu consumidor de webhook pode armazenar e gerenciar logs de eventos.
- KYC Essencial Gratuito e Design Modular: A Didit oferece KYC Essencial Gratuito, permitindo que você comece a construir e testar seus consumidores de webhook sem custos iniciais. Nosso design modular significa que você pode integrar facilmente produtos específicos de verificação de identidade — como Verificação de ID para checagem de documentos, Liveness Passiva e Ativa para prevenção de fraudes, ou Estimativa de Idade para verificação de idade — e receber atualizações em tempo real via webhooks.
Ao aproveitar o sistema de webhook robusto e seguro da Didit, os desenvolvedores podem se concentrar mais na lógica central de sua aplicação e menos nas complexidades de proteger e deduplicar eventos recebidos, levando a fluxos de trabalho de verificação de identidade mais resilientes e confiáveis.
Pronto para Começar?
Pronto para ver a Didit em ação? Obtenha uma demonstração gratuita hoje.
Comece a verificar identidades gratuitamente com o plano gratuito da Didit.