주제

HMAC 인증 및 보안

FastOG의 HMAC-SHA256 인증을 사용하여 HMAC 서명된 OG 이미지 URL을 보호하세요. 이 가이드에서는 모든 요청의 서명, 검증, 문제 해결 방법을 다루므로, 구독 기반의 무제한 렌더링(월 렌더링 할당량 및 초과 요금 없음)으로 동적 Open Graph 이미지를 즉시 제공할 수 있습니다. 가입 후 Dynamic API 플랜을 선택하고, 대시보드에서 API 키와 HMAC 시크릿을 생성하세요(유료 API 렌더링은 깨끗합니다). 서버에서 한 번 서명하고 몇 분 안에 통합하세요.

🚀 빠른 시작

HMAC 서명이 처음이신가요? 여기서 시작하세요:

  1. 빠른 시작 가이드 — 5분 안에 시작할 수 있습니다
  2. JavaScript 튜토리얼 — Node.js/Next.js 개발자를 위한 완전한 가이드
  3. 모든 프레임워크 튜토리얼 — 원하는 스택을 선택하세요:

📚 문서 색인

핵심 개념

  • HMAC 서명 가이드 — 알고리즘 세부 사항, 요구 사항, JavaScript·PHP·Python 예제를 포함한 전체 참조 자료
  • HMAC 검증 — 서버 측 구현 세부 사항, 보안 기능, 오류 응답

튜토리얼

빠른 참조

알고리즘

method = "GET"
path = "/api/v1/og"
canonicalQuery = every query param EXCEPT `s` (including `key`): array values sorted too; each pair rfc3986Encode(key)=rfc3986Encode(value); pairs sorted lexicographically and joined with "&"

message = method + path + "\n" + canonicalQuery
signature = hex(HMAC-SHA256(message, hmac_secret))

URL: /api/v1/og?title=Hello&key=sk_quick_123abc&s=<signature>

쿼리 매개변수

매개변수 설명 예시
key 전체 API 키 sk_quick_123abc
s HMAC-SHA256 서명 (16진수 64자) 9f8a1b2c3d4e...

오류 코드

코드 HTTP 상태 설명
missing_signature 401 key 또는 s 매개변수 누락
invalid_signature 401 서명이 일치하지 않음

🎯 사용 사례

블로그 게시물

블로그 게시물용 동적 OG 이미지 생성:

javascript
const ogUrl = generateSignedOgUrl({
    template: "blog",
    title: post.title,
    subtitle: post.excerpt,
    author: post.author.name,
});

// <meta property="og:image" content="{ogUrl}" />

이커머스 상품

상품 페이지용 OG 이미지 생성:

javascript
const ogUrl = generateSignedOgUrl({
    template: "ecommerce",
    title: product.name,
    price: product.price,
    image: product.image,
});

사용자 후기

사용자 후기 인용문용 OG 이미지 생성:

javascript
const ogUrl = generateSignedOgUrl({
    template: "testimonial",
    author_name: user.name,
    author_avatar: user.avatarUrl,
    quote: user.bio,
});

🔐 보안

모범 사례

  1. 비밀 정보를 안전하게 저장 — 환경 변수 또는 비밀 관리자(secrets manager) 사용
  2. 클라이언트 측 코드에 HMAC 비밀을 노출하지 않기 — 서버에서만 서명
  3. HTTPS 사용 — 중간자 공격(MITM) 방지
  4. 비밀을 주기적으로 교체 — 특히 유출된 경우
  5. 실패한 서명 모니터링 — 반복적인 실패는 공격을 의미할 수 있음
  6. 사용자별 격리 — 각 API 키는 고유한 HMAC 비밀을 보유

HMAC 비밀 확인 방법

  1. 대시보드 → API 키로 이동
  2. 새 API 키 생성
  3. HMAC 비밀 복사 (한 번만 표시됨!)
  4. 환경 변수에 저장
bash
# .env
FASTOG_HMAC_SECRET=<your-64-char-hex-secret>

🧪 테스트

테스트 URL 생성

bash
# Node.js
node -e "
const crypto = require('crypto');
const enc = (s) => encodeURIComponent(s).replace(/[!'()*]/g, (c) => '%' + c.charCodeAt(0).toString(16).toUpperCase());
const all = { title: 'Test', key: 'sk_quick_123abc' };
const pairs = [];
for (const [k, v] of Object.entries(all)) for (const vv of Array.isArray(v) ? v : [v]) pairs.push(enc(k) + '=' + enc(vv));
pairs.sort();
const canonical = pairs.join('&');
const sig = crypto.createHmac('sha256', 'YOUR_HMAC_SECRET').update('GET/api/v1/og\n' + canonical).digest('hex');
console.log('https://fastog.com/api/v1/og?title=Test&key=sk_quick_123abc&s=' + sig);
"

curl로 테스트

bash
curl "https://fastog.com/api/v1/og?title=Test&key=sk_quick_123abc&s=<signature>"

예상 응답

  • ✅ 유효한 서명 → OG 이미지 반환 (템플릿 매개변수가 유효하지 않으면 422 반환)
  • ❌ 유효하지 않은 서명 → {"code": "invalid_signature"}
  • ❌ 매개변수 누락 → {"code": "missing_signature"}

🛠 문제 해결

서명이 일치하지 않음

  1. 올바른 HMAC 시크릿을 사용하고 있는지 확인하세요(대시보드에서 API 키 확인)
  2. 표준 쿼리(canonical query)를 확인하세요: s을 제외한 모든 쿼리 매개변수(key 포함), 값은 rfc3986으로 인코딩, 키는 사전순으로 정렬
  3. 서명이 소문자 16진수(64자)인지 확인하세요

📖 추가 자료

❓ FAQ

Q: 헤더 대신 쿼리 매개변수를 사용하는 이유는 무엇인가요?
A: OG 이미지는 소셜 네트워크 크롤러(LinkedIn, Twitter, Facebook)가 가져오며, 이들은 사용자 정의 헤더를 보내지 않습니다. 서명은 반드시 URL에 포함되어야 합니다.

Q: 여러 요청에 동일한 서명을 사용할 수 있나요?
A: 네. 서명은 정확한 쿼리(s 제외)에서 계산되므로, 매개변수가 변경되지 않는 한 동일한 서명된 URL은 유효합니다. 매개변수(key 포함)를 변경하면 다시 서명해야 합니다.

Q: 모든 템플릿에 대해 요청에 서명해야 하나요?
A: 네. /api/v1/og에 대한 모든 요청에는 HMAC 서명이 필요합니다.

Q: HMAC 비밀 키가 유출되면 어떻게 되나요?
A: 대시보드에서 API 키를 폐기하고 새 키를 생성하세요. 각 API 키에는 고유한 HMAC 비밀 키가 있습니다.

Q: 내부 서비스에 대해 HMAC 검증을 비활성화할 수 있나요?
A: 맞춤 솔루션은 지원팀에 문의하세요. HMAC 검증은 모든 공개 API 엔드포인트에 필수입니다.

🆘 지원

도움이 필요하신가요?

무료로 체험해 보세요 — 가입 불필요

몇 초 만에 동적 OG 이미지를 미리 보고 테스트하세요.

무료 OG 이미지 테스터 열기

A BeCaSimulations site