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 요청에는 서명 검증이 포함됩니다.
작동 방식:
- finlight는 webhook을 보낼 때 타임스탬프를 생성합니다
- 다음과 같이 연결하여 메시지를 만듭니다:
timestamp + '.' + payload - webhook의 비밀 키를 사용하여 HMAC-SHA256으로 메시지에 서명합니다
- 서명과 타임스탬프를 모두 헤더로 전송합니다
포함되는 헤더:
X-Webhook-Signature: sha256=computed-signature
X-Webhook-Timestamp: 2024-01-15T10:30:00.000Z
서명 알고리즘:
message = timestamp + '.' + JSON.stringify(payload)
signature = HMAC-SHA256(message, webhook_secret)
SECURITY필수 지침
보안 모범 사례
타임스탬프 검증
요청 타임스탬프를 검증하여 재생 공격을 방지하세요:
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 테스트 가이드를 확인하세요.