작은 블로그 댓글은 방문자가 많지 않아도 스팸이 먼저 옵니다.
영문 광고, 카지노 링크, 가짜 문의, 자동화된 POST 요청이 쌓이면 댓글 기능을 켜두기 어려워집니다.

Cloudflare Turnstile은 이런 폼 스팸을 줄이는 데 쓸 수 있는 가벼운 선택지입니다.
다만 프론트엔드에 위젯만 붙이면 끝나는 기능은 아닙니다. Cloudflare 문서도 Turnstile 구현은 서버에서 Siteverify API를 호출해 토큰을 검증해야 완료된다고 안내합니다.

이 글은 2026년 5월 28일 기준 Cloudflare 공식 문서를 바탕으로, 작은 블로그 댓글 폼에 Turnstile을 붙일 때 필요한 흐름을 정리합니다.

먼저 결론

댓글 스팸 방지는 Turnstile 하나로 끝내기보다 아래 4개를 같이 둬야 합니다.

  1. Turnstile client widget
  2. server-side token validation
  3. IP 또는 fingerprint 기준 rate limit
  4. 댓글 moderation 또는 링크 제한

Turnstile은 “사람인지 확인하는 관문”이고, 댓글 시스템의 정책 전체를 대신하지는 않습니다.

기본 흐름

작은 블로그 댓글 폼에서는 보통 이런 순서로 붙입니다.

  1. Cloudflare 대시보드에서 Turnstile widget을 만듭니다.
  2. 댓글 폼에 sitekey를 넣어 widget을 렌더링합니다.
  3. 사용자가 댓글을 제출하면 cf-turnstile-response 토큰을 서버로 보냅니다.
  4. 서버는 secret key와 token을 Cloudflare Siteverify API로 검증합니다.
  5. success가 true일 때만 댓글 저장 로직으로 넘어갑니다.
  6. 실패하면 댓글을 저장하지 않고 다시 시도하게 합니다.

중요한 점은 4번입니다.
브라우저에서 위젯이 보였다는 사실만으로는 보호가 끝나지 않습니다.

1. Managed widget부터 시작합니다

Cloudflare Turnstile widget에는 Managed, Non-Interactive, Invisible 모드가 있습니다.
Cloudflare 문서 기준 Managed는 방문자 위험도에 따라 비대화형 또는 체크박스 challenge를 자동으로 선택하는 권장 모드입니다.

작은 블로그 댓글에는 보통 Managed가 가장 무난합니다.

  • 스팸이 적을 때는 방문자 마찰이 낮습니다.
  • 의심스러운 요청에는 추가 확인을 요구할 수 있습니다.
  • 구현과 설명이 단순합니다.

Invisible 모드는 화면을 깔끔하게 만들 수 있지만, 개인정보 처리방침에 Turnstile Privacy Addendum 참조가 필요하다는 조건이 있습니다.
처음 붙일 때는 Managed로 시작하고, 실제 실패율과 댓글 전환을 본 뒤 조정하는 편이 안전합니다.

2. secret key는 서버에만 둡니다

Turnstile에는 sitekey와 secret key가 있습니다.

  • sitekey: 브라우저에 노출돼도 되는 공개 키
  • secret key: 서버 검증에 쓰는 비공개 키

작은 사이트에서 흔한 실수는 secret key를 프론트엔드 코드나 정적 빌드 결과에 넣는 것입니다.
Astro 정적 페이지, React 컴포넌트, HTML 안에 secret key가 들어가면 그대로 공개됩니다.

권장 구조는 이렇습니다.

브라우저 댓글 폼
  -> cf-turnstile-response 포함해 /api/comments 로 POST
  -> Node.js API가 TURNSTILE_SECRET으로 Siteverify 호출
  -> 성공 시 댓글 저장

환경 변수 이름은 예를 들어 이렇게 둘 수 있습니다.

PUBLIC_TURNSTILE_SITE_KEY=0x...
TURNSTILE_SECRET_KEY=0x...

PUBLIC_ 접두어가 붙는 값은 노출돼도 되는 값에만 사용해야 합니다.

3. 서버 검증은 필수입니다

Cloudflare Siteverify API의 endpoint는 다음과 같습니다.

POST https://challenges.cloudflare.com/turnstile/v0/siteverify

서버는 최소한 아래 값을 보냅니다.

  • secret: Cloudflare 대시보드의 secret key
  • response: 브라우저가 보낸 Turnstile token
  • remoteip: 선택 사항이지만 가능하면 방문자 IP

검증 결과가 success: true일 때만 댓글을 저장합니다.

의사 코드는 이렇습니다.

async function verifyTurnstile(token, remoteip) {
  const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      secret: process.env.TURNSTILE_SECRET_KEY,
      response: token,
      remoteip,
    }),
  });

  const result = await response.json();
  return result.success === true;
}

여기서 중요한 규칙은 실패 시 “일단 저장하고 나중에 지우기”가 아니라 저장 전 차단입니다.

4. 토큰은 짧고 한 번만 쓴다고 봐야 합니다

Cloudflare 문서 기준 Turnstile token은 300초 동안 유효하고, 한 번만 검증할 수 있습니다.
이미 검증한 token을 다시 쓰면 timeout-or-duplicate 오류가 날 수 있습니다.

댓글 폼에서는 이 점 때문에 아래 처리가 필요합니다.

  1. 사용자가 오래 머문 뒤 제출하면 token이 만료될 수 있습니다.
  2. 제출 실패 후 다시 제출할 때 widget reset이 필요할 수 있습니다.
  3. 브라우저 새로고침이나 중복 클릭을 고려해야 합니다.
  4. 서버가 retry할 수 있다면 idempotency key를 고려합니다.

즉 “댓글 쓰고 한참 뒤 제출” 시나리오를 꼭 테스트해야 합니다.

5. Turnstile만으로 링크 스팸은 다 막히지 않습니다

Turnstile은 자동화된 요청을 줄여주지만, 사람이 직접 넣는 스팸이나 저품질 댓글까지 모두 막지는 않습니다.

작은 블로그라면 아래 규칙을 같이 두는 편이 현실적입니다.

  • 댓글 본문 링크 개수 제한
  • 같은 IP의 짧은 시간 내 반복 제출 제한
  • 새 댓글은 기본 pending 상태로 저장
  • 금칙어보다 URL 패턴과 반복 문구를 우선 확인
  • 관리자 댓글 승인 UI 제공
  • 너무 긴 댓글, 빈 댓글, 동일 댓글 재제출 차단

댓글 스팸은 보안 문제이면서 운영 문제입니다.
처음부터 완전 자동 공개보다 검증 통과 후 moderation 흐름이 안전합니다.

6. Cloudflare WAF와 섞을 때는 역할을 나눕니다

Cloudflare에는 Turnstile 외에도 WAF, managed challenge, rate limiting 같은 기능이 있습니다.
작은 블로그에서는 처음부터 복잡하게 묶기보다 역할을 나누는 편이 좋습니다.

  • 댓글 제출 endpoint: Turnstile server validation
  • 너무 잦은 POST: rate limit
  • 관리자 경로: Access 또는 별도 인증
  • 사이트 전체 공격: WAF rule

Turnstile pre-clearance는 Cloudflare 보호 도메인에서 clearance cookie를 활용하는 기능입니다.
일반 댓글 폼만 막는 목적이라면 먼저 기본 Siteverify 검증부터 붙이는 편이 낫습니다.

적용 전 체크리스트

Turnstile을 댓글에 붙이기 전에 아래를 확인합니다.

  1. sitekey와 secret key를 분리했는가
  2. secret key가 정적 빌드 결과에 들어가지 않는가
  3. 서버에서 Siteverify API를 호출하는가
  4. 검증 실패 시 댓글 저장이 차단되는가
  5. token 만료와 중복 제출을 처리하는가
  6. 댓글 POST endpoint에 rate limit이 있는가
  7. 링크 스팸과 moderation 정책이 있는가
  8. Invisible mode를 쓰면 privacy policy 조건을 확인했는가

한 줄 결론

Cloudflare Turnstile은 작은 블로그 댓글 스팸을 줄이는 좋은 출발점입니다.
하지만 진짜 보호는 위젯 표시가 아니라 서버 검증, rate limit, 댓글 정책까지 이어질 때 완성됩니다.

같이 보면 좋은 글

출처