본문 바로가기
Backend2026년 6월 12일3분 읽기

Webhook 안전하게 받기 — 서명 검증과 멱등 처리

YS
김영삼
조회 415
Webhook 안전하게 받기 — 서명 검증과 멱등 처리

핵심 요약

외부 서비스 webhook은 누구나 같은 URL로 위조 요청을 보낼 수 있으므로 HMAC 서명 검증이 필수다. 또 같은 이벤트가 재시도로 여러 번 올 수 있으니 이벤트 ID로 멱등 처리해 중복 반영을 막아야 한다(특히 결제·재고).

1. 서명 검증

const sig = req.headers['x-signature']
const expected = crypto
  .createHmac('sha256', SECRET)
  .update(rawBody)          // 파싱 전 원본 바디
  .digest('hex')
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected)))
  return res.status(401).end()

2. 멱등 처리

  • 이벤트 ID를 유니크 키로 저장 → 이미 있으면 무시
  • 처리와 저장을 한 트랜잭션으로
  • 빠르게 200 응답하고 무거운 작업은 큐로(타임아웃 재시도 방지)

3. 함정

  • JSON 파싱 후 바디로 서명 검증하면 직렬화 차이로 실패 — 원본 raw body로 검증
  • 문자열 단순 비교는 타이밍 공격에 취약 — timingSafeEqual 사용
  • 200을 늦게 주면 공급자가 재전송 → 중복. 먼저 접수 응답 후 처리

자주 묻는 질문

왜 raw body로 검증해야 하나요?

서명은 발신자가 보낸 바이트 그대로를 기준으로 만들어집니다. JSON 파싱 후 다시 직렬화하면 공백·키 순서가 달라져 서명이 안 맞습니다. 미들웨어에서 원본 바디를 보존하세요.

같은 이벤트가 두 번 왔어요.

네트워크 타임아웃 등으로 공급자가 재시도한 것입니다. 이벤트 ID를 유니크로 저장해 두 번째는 무시하세요.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록