정적 사이트에 댓글을 넣으면 상태 저장과 spam 대책이 필요해집니다.
Acecore는 외부 댓글 SaaS나 widget을 쓰지 않았습니다. PR #101에서 Cloudflare 안의 기능만으로 구현했습니다.
- Astro가 UI를 렌더링합니다.
- Cloudflare Pages Functions가
/api/comments를 제공합니다. - Cloudflare D1이 댓글을 저장합니다.
- Cloudflare Turnstile이 POST를 보호합니다.
wrangler.jsonc가 preview와 production을 나눕니다.
핵심은 댓글 영역이 페이지 안의 외부 서비스가 아니라, 기존 Cloudflare 구성의 일부라는 점입니다.
구조
| 계층 | 파일 또는 서비스 |
|---|---|
| UI | src/components/BlogComments.astro |
| 기사 배치 | src/views/BlogPostPage.astro |
| API | functions/api/comments.ts |
| 저장소 | D1 binding COMMENTS_DB |
| 보호 | Cloudflare Turnstile |
| schema | migrations/0001_create_blog_comments.sql |
UI는 GET /api/comments?slug=...&locale=...로 읽고, POST /api/comments로 제출합니다.
Function은 origin, payload, Turnstile, rate limit, 중복, 금지 내용을 검증한 뒤 저장합니다.
D1을 선택한 이유
댓글은 기사별 조회, 시간순 정렬, soft delete, 중복 검사, client별 제한이 필요합니다. SQL로 표현하기 쉬운 작업입니다.
보이는 댓글은 deleted_at IS NULL인 행입니다. spam은 물리 삭제하지 않고 deleted_at만 채워 숨길 수 있습니다.
쿼리는 prepared statement와 bind()를 사용해 사용자 입력을 SQL 문자열에 직접 붙이지 않습니다.
Wrangler로 환경을 나누기
COMMENTS_DB는 wrangler.jsonc에 정의합니다. preview는 acecore-comments-preview, production은 acecore-comments-production을 사용합니다.
PR preview가 production DB에 쓰지 않도록 하는 것이 중요합니다.
Turnstile은 서버에서 검증
브라우저의 widget만으로는 부족합니다.
Pages Function이 token을 Cloudflare Siteverify로 보내고, 성공한 경우에만 저장합니다. 반환된 hostname도 allowlist와 비교합니다.
spam 대책
첫 버전은 엄격합니다.
- URL 금지
- 이메일 주소 금지
- HTML 금지
- Markdown 링크 금지
- 과도한 반복 문자 금지
- 홍보성 단어 금지
- honeypot 사용
또한 메모리 rate limit과 D1 기반 rate limit을 함께 둡니다. IP는 원문 저장 대신 salt를 섞은 hash로 사용합니다.
SEO
댓글은 클라이언트에서 읽고, 영역에는 data-pagefind-ignore를 붙였습니다. 따라서 댓글은 본문 검색 index에 들어가지 않습니다.
기업 블로그에서는 본문과 댓글의 역할을 분리하는 편이 안전합니다.
정리
외부 댓글 서비스는 편하지만 필수는 아닙니다.
Cloudflare Pages를 쓰는 사이트라면 Pages Functions, D1, Turnstile, Wrangler만으로 가벼운 댓글 기능을 만들 수 있습니다.
참고
왜 외부 댓글 서비스를 쓰지 않았나요?
D1로 충분한가요?
Turnstile을 프런트에만 두면 되나요?
댓글
Gui
Acecore 대표. 업무 시스템, 웹, DB/인프라, 품질, AI 활용을 사업 과제 정리부터 설계, 도입 후 개선까지 이어지는 흐름으로 추진합니다. C#/.NET 기반의 실무 구현력을 바탕으로 PHP/JavaScript, SQL Server/PostgreSQL/MySQL, Linux/Windows Server도 고려하며, 요구사항 정리, 기술 선택, 품질 기준, GitHub 기반 개발 운영을 하나의 흐름으로 설계합니다. 생성형 AI는 개발, 검증, 정보 정리 등 업무 프로세스에 도입해 소규모 팀도 빠르고 확실하게 성과를 낼 수 있는 실무 기반으로 활용하고 있습니다.