Didit 이벤트를 위한 Ruby on Rails 기반 멱등 웹훅 소비자 구축 (KO)
안정적인 데이터 처리를 위해서는 견고한 웹훅 소비자 구축이 중요하며, 특히 Didit과 같은 신원 확인 플랫폼의 실시간 이벤트에 있어서 더욱 그렇습니다.

데이터 무결성 보장멱등성은 웹훅 이벤트를 안정적으로 처리하고 중복 작업을 방지하며 애플리케이션에서 일관된 상태를 유지하는 데 필수적입니다.
웹훅 서명 활용들어오는 요청의 신뢰성과 무결성을 확인하기 위해 항상 웹훅 서명을 확인하여 변조 및 스푸핑으로부터 보호하세요.
고유 이벤트 ID 활용웹훅 페이로드에 제공된 고유 이벤트 ID를 저장하고 확인하여 중복 전달을 효과적으로 감지하고 폐기합니다.
Didit의 강력한 웹훅 시스템Didit은 HMAC 서명과 고유 이벤트 ID가 포함된 안전하고 버전 관리되는 웹훅을 제공하여 멱등 소비자 구현을 단순화하고 중요한 신원 확인 워크플로를 위한 안정적인 이벤트 전달을 보장합니다.
웹훅 멱등성의 과제
웹훅은 서비스 간 실시간 통신을 위한 강력한 메커니즘으로, 애플리케이션이 다른 시스템에서 발생하는 이벤트에 즉시 반응할 수 있도록 합니다. 그러나 웹훅의 분산된 특성으로 인해 이벤트가 여러 번 전달될 수 있습니다. 네트워크 오류, 시간 초과 또는 재시도는 모두 중복 웹훅 페이로드로 이어질 수 있습니다. 적절한 처리 없이는 이러한 중복이 중복 기록 생성, 중복 작업 트리거 또는 데이터 손상과 같은 애플리케이션의 심각한 문제를 야기할 수 있습니다.
여기서 멱등성이 중요해집니다. 멱등 작업은 한 번 실행되든 여러 번 실행되든 동일한 결과를 생성하는 작업입니다. 웹훅 소비자의 경우, 이는 웹훅 페이로드가 여러 번 수신되더라도 주어진 이벤트를 한 번만 처리하도록 시스템을 설계하는 것을 의미합니다. Didit과 같은 플랫폼의 신원 확인 결과와 같은 민감한 데이터를 다룰 때 멱등성을 보장하는 것은 좋은 관행일 뿐만 아니라 데이터 무결성과 시스템 신뢰성을 유지하는 데 필수적입니다.
보안 및 신뢰성을 위한 웹훅 서명 확인
웹훅 페이로드를 처리하기 전에 가장 중요하고 첫 번째 단계는 그 신뢰성을 확인하는 것입니다. 이는 웹훅이 예상되는 발신자(예: Didit)로부터 실제로 시작되었는지, 그리고 그 내용이 전송 중에 변조되지 않았음을 보장합니다. 예를 들어 Didit의 웹훅은 공유 비밀 키를 사용하여 생성된 HMAC 서명을 요청 헤더에 포함합니다.
Ruby on Rails 애플리케이션에서는 Didit 계정에서 공유 비밀 키를 검색해야 합니다(비즈니스 콘솔을 통해 또는 API를 사용하여 프로그래밍 방식으로 액세스할 수 있습니다). 웹훅이 도착하면 요청 본문과 비밀 키를 사용하여 자체 HMAC 서명을 계산합니다. 이 계산된 서명은 웹훅 헤더에 제공된 서명과 비교됩니다. 일치하지 않으면 요청은 즉시 거부되어야 합니다.
class DiditWebhooksController < ApplicationController
skip_before_action :verify_authenticity_token
def create
# 환경 변수에서 공유 비밀 키를 검색합니다.
secret = ENV['DIDIT_WEBHOOK_SECRET']
payload = request.body.read
signature = request.headers['X-Didit-Signature'] # 또는 유사한 헤더 이름
unless verify_signature(payload, signature, secret)
head :unauthorized
return
end
# 확인 후 웹훅 페이로드를 처리합니다.
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)
# ... 처리 구현 ...
end
end
Didit은 웹훅 구성의 일부로 secret_shared_key를 제공하여 이를 단순화하며, 이는 API를 통해 검색하거나 필요에 따라 순환할 수 있습니다. 이 보안 메커니즘은 신분증 확인 또는 생체 인식 확인과 같은 결과의 무결성이 가장 중요한 모든 신원 확인 워크플로에 필수적입니다.
고유 이벤트 식별자를 사용한 멱등성 구현
웹훅의 신뢰성을 확인한 후 다음 단계는 멱등성을 보장하는 것입니다. Didit을 포함한 대부분의 잘 설계된 웹훅 시스템은 각 이벤트에 고유 식별자를 제공합니다. 이 ID는 중복 처리를 감지하고 방지하는 데 중요합니다. Didit의 웹훅(특히 권장되는 v3)의 경우 각 이벤트 페이로드에는 이 목적에 사용할 수 있는 고유 ID가 포함됩니다.
전략은 이러한 이벤트 ID를 데이터베이스에 저장하고 처리하기 전에 이를 확인하는 것입니다. 일반적인 패턴은 EventLog 또는 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
웹훅이 도착하면:
- 페이로드에서 고유한
event_id를 추출합니다. - 이
event_id를 사용하여 새WebhookEvent레코드를 생성하려고 시도합니다. - 고유 제약 조건 위반으로 인해 생성이 실패하면(즉,
event_id가 이미 존재한다는 의미) 중복임을 알 수 있으며 안전하게 무시하거나 그렇게 기록할 수 있습니다. - 생성이 성공하면 이벤트를 처리하고 그에 따라 상태를 표시합니다.
class DiditWebhooksController < ApplicationController
# ... (위와 동일한 서명 확인) ...
def create
# ... (서명 확인) ...
event_data = JSON.parse(payload)
event_id = event_data['id'] # 'id'가 Didit의 고유 이벤트 식별자라고 가정합니다.
# 원자성을 보장하기 위해 트랜잭션을 사용합니다.
ActiveRecord::Base.transaction do
webhook_event = WebhookEvent.find_or_initialize_by(event_id: event_id)
if webhook_event.persisted? # 이미 존재한다면 중복입니다.
Rails.logger.info "중복 웹훅 이벤트 수신: #{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!
# 장기 실행 작업을 위해 백그라운드 작업에서 이벤트를 처리합니다.
DiditEventProcessorJob.perform_later(webhook_event.id)
head :ok
end
rescue ActiveRecord::RecordNotUnique # event_id에 대한 경쟁 조건을 처리합니다.
Rails.logger.warn "웹훅 이벤트에 대한 경쟁 조건 감지: #{event_id}. 무시합니다."
head :ok
rescue JSON::ParserError
head :bad_request
rescue => e
Rails.logger.error "웹훅 처리 오류: #{e.message}"
head :internal_server_error
end
end
이 접근 방식은 실제 처리를 위한 백그라운드 작업과 결합되어 웹훅 엔드포인트가 신속하게 응답하여 발신자의 재시도를 방지하는 동시에 중복을 안정적으로 처리하도록 보장합니다.
경쟁 조건 및 트랜잭션 처리
고유 인덱스가 있더라도 두 개의 동일한 웹훅이 거의 동시에 도착하면 경쟁 조건이 발생할 수 있습니다. 둘 다 첫 번째 트랜잭션이 커밋되기 전에 새 WebhookEvent 레코드를 생성하려고 시도할 수 있습니다. 이를 완화하려면:
- 데이터베이스 트랜잭션 사용:
find_or_initialize_by및 후속 처리 로직을 데이터베이스 트랜잭션 내에 래핑합니다. 이렇게 하면 전체 작업이 성공하거나 실패하여 데이터 일관성을 유지할 수 있습니다. RecordNotUnique처리:ActiveRecord::RecordNotUnique예외를 포착할 준비를 합니다. 새WebhookEvent를 저장하려고 할 때 이 예외가 발생하면 다른 프로세스가 이미 이벤트를 삽입한 경쟁 조건임을 나타내며, 이를 안전하게 중복으로 처리할 수 있습니다.
핵심 애플리케이션 데이터를 수정하는 작업의 경우, 트랜잭션을 해당 변경 사항을 포함하도록 확장하거나, 적어도 이벤트를 처리하는 백그라운드 작업이 수정하는 애플리케이션 데이터에 대한 자체 멱등성 검사를 구현하도록 보장하는 것이 중요합니다.
Didit이 도움이 되는 방법
Didit은 신뢰성과 보안을 염두에 두고 설계된 AI 기반, 개발자 우선 신원 플랫폼으로, 견고한 웹훅 소비자를 더 쉽게 구현할 수 있도록 합니다. 당사의 모듈식 아키텍처는 멱등 처리를 지원하도록 본질적으로 설계된 깔끔한 API와 보안 웹훅을 제공합니다.
- 보안 웹훅: Didit의 웹훅은 강력한 HMAC 서명(관리하고 순환할 수 있는
secret_shared_key사용)을 제공하여 모든 이벤트의 신뢰성과 무결성을 보장합니다. 멱등성의 이 중요한 첫 번째 단계는 내장되어 있습니다. 최적의 페이로드 구조를 위해webhook_version(v3 권장)을 지정할 수도 있습니다. - 고유 이벤트 식별자: 모든 Didit 웹훅 이벤트에는 고유 식별자가 포함되어 위에 설명된 중복 제거 로직을 쉽게 구현할 수 있습니다.
- 구성 가능한 데이터 보존: Didit을 사용하면 확인 데이터가 저장되는 기간을 제어할 수 있습니다. 비즈니스 콘솔 또는 API를 통해 데이터 보존 정책을 1개월에서 10년까지 설정하거나 무제한으로 null로 설정할 수도 있습니다. 이를 통해 GDPR과 같은 규정 준수 요구 사항을 충족하면서 데이터 공간을 관리할 수 있습니다. 이는 웹훅 소비자가 이벤트 로그를 저장하고 관리하는 방식과도 연결됩니다.
- 무료 핵심 KYC 및 모듈식 디자인: Didit은 무료 핵심 KYC를 제공하여 초기 비용 없이 웹훅 소비자를 구축하고 테스트할 수 있도록 합니다. 당사의 모듈식 디자인은 문서 확인을 위한 신분증 확인, 사기 방지를 위한 수동 및 능동 생체 인식 또는 연령 확인을 위한 연령 추정과 같은 특정 신원 확인 제품을 쉽게 통합하고 웹훅을 통해 실시간 업데이트를 받을 수 있음을 의미합니다.
Didit의 강력하고 안전한 웹훅 시스템을 활용함으로써 개발자는 애플리케이션의 핵심 로직에 더 집중하고 들어오는 이벤트를 보호하고 중복 제거하는 복잡성에 덜 신경 쓸 수 있으므로 더 탄력적이고 신뢰할 수 있는 신원 확인 워크플로를 만들 수 있습니다.
시작할 준비가 되셨습니까?
Didit의 작동 방식을 보고 싶으십니까? 지금 무료 데모를 받으세요.
Didit의 무료 티어로 무료로 신원 확인을 시작하세요.