이 페이지는 기계 번역되었습니다. 영어 버전이 원본이며 더 정확하거나 최신일 수 있습니다. 영어로 보기

Webhook 인증 - 엔드포인트 보호

finlight는 webhook 전송을 보호하기 위해 여러 인증 방법을 제공합니다. 모든 webhook에는 기본적으로 서명 검증이 포함되며, 보안 강화를 위한 선택적 추가 인증 계층을 사용할 수 있습니다.

finlight는 개별적으로 또는 조합하여 사용할 수 있는 네 가지 인증 방법을 지원합니다:

없음추가 인증 없음

없음

기본 서명 검증 외에 추가 인증이 없습니다.

사용 시기:

  • 테스트 및 개발 환경
  • 보안 네트워크 뒤의 내부 엔드포인트
  • 서명 검증이 충분한 보안을 제공하는 경우

참고: 이 설정과 관계없이 모든 webhook 요청에는 서명 검증이 계속 포함됩니다.


FINLIGHT_KEY사용자 지정 헤더

X-Finlight-Key 헤더

각 webhook 요청과 함께 사용자 지정 X-Finlight-Key 헤더로 API 키를 전송합니다.

구성:

  • webhook 설정 중에 API 키를 제공합니다
  • 키는 X-Finlight-Key 헤더에 포함됩니다

구현: 엔드포인트는 들어오는 헤더를 검증해야 합니다:

const finlightKey = req.headers['x-finlight-key']
if (finlightKey !== 'your-expected-api-key') {
  return res.status(401).send('Invalid API key')
}

전송되는 헤더:

X-Finlight-Key: your-api-key-value
X-Webhook-Signature: sha256=signature
X-Webhook-Timestamp: 2024-01-15T10:30:00.000Z

BASIC사용자 이름/비밀번호

기본 인증

사용자 이름/비밀번호 자격 증명을 사용하는 HTTP 기본 인증.

구성:

  • webhook 설정 중에 사용자 이름과 비밀번호를 설정합니다
  • 자격 증명은 base64로 인코딩되어 Authorization 헤더로 전송됩니다

구현: 엔드포인트는 표준 HTTP 기본 인증을 받습니다:

const auth = req.headers.authorization
if (!auth || !auth.startsWith('Basic ')) {
  return res.status(401).send('Missing Basic Auth')
}

const credentials = Buffer.from(auth.slice(6), 'base64').toString()
const [username, password] = credentials.split(':')

if (username !== 'expected-user' || password !== 'expected-pass') {
  return res.status(401).send('Invalid credentials')
}

전송되는 헤더:

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
X-Webhook-Signature: sha256=signature
X-Webhook-Timestamp: 2024-01-15T10:30:00.000Z

SIGNATURE항상 포함됨

서명 검증

자동 보안: 선택한 인증 방법과 관계없이 모든 webhook 요청에는 서명 검증이 포함됩니다.

작동 방식:

  1. finlight는 webhook을 보낼 때 타임스탬프를 생성합니다
  2. 다음과 같이 연결하여 메시지를 만듭니다: timestamp + '.' + payload
  3. webhook의 비밀 키를 사용하여 HMAC-SHA256으로 메시지에 서명합니다
  4. 서명과 타임스탬프를 모두 헤더로 전송합니다

포함되는 헤더:

X-Webhook-Signature: sha256=computed-signature
X-Webhook-Timestamp: 2024-01-15T10:30:00.000Z

서명 알고리즘:

message = timestamp + '.' + raw_request_body
signature = HMAC-SHA256(message, webhook_secret)

X-Webhook-Timestamp 헤더가 없는 경우 메시지는 원시 본문 그 자체입니다. 결과는 상수 시간으로 비교하고, 타임스탬프가 5분보다 오래된 전달은 거부하세요.

공식 클라이언트로 검증하기

모든 클라이언트 라이브러리에는 전체 검사를 대신 수행하는 헬퍼가 포함되어 있습니다. 서명의 sha256= 접두사를 처리하고, 상수 시간으로 비교하며, 5분의 재전송 허용 범위를 적용하고, 파싱된 기사를 반환합니다. 검증에 실패하면 예외를 던지거나 오류를 반환하므로, 항상 4xx로 응답하고 페이로드는 절대 처리하지 마세요.

웹훅 검증

import express from 'express'
import { WebhookService } from 'finlight-client'

const app = express()

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  try {
    const article = WebhookService.constructEvent(
      req.body.toString(),
      req.headers['x-webhook-signature'] as string,
      process.env.WEBHOOK_SECRET!,
      req.headers['x-webhook-timestamp'] as string,
    )

    console.log('New article:', article.title)
    res.sendStatus(200)
  } catch (err) {
    console.error('Webhook verification failed:', err)
    res.sendStatus(400)
  }
})

SECURITY필수 지침

보안 모범 사례

타임스탬프 검증

위의 constructEvent 헬퍼는 이미 5분의 재전송 허용 범위를 적용하므로, 이 내용은 서명을 직접 검증하는 경우에만 필요합니다:

function isTimestampValid(timestamp, toleranceSeconds = 300) {
  const now = Date.now()
  const requestTime = new Date(timestamp).getTime()
  const difference = Math.abs(now - requestTime) / 1000

  return difference <= toleranceSeconds
}

자격 증명의 안전한 저장

  • 환경 변수: 모든 비밀을 환경 변수에 저장합니다
  • 비밀 관리: AWS Secrets Manager, HashiCorp Vault 또는 유사 도구를 사용합니다
  • 하드코딩 금지: 비밀을 버전 관리에 커밋하지 마세요
  • 정기적 교체: webhook 비밀을 주기적으로 갱신합니다

webhook 설정 안내는 webhook 기본 문서를 참조하세요. 포괄적인 테스트는 webhook 테스트 가이드를 확인하세요.