서버 없이 직접 만든 댓글 시스템: Cloudflare Worker+D1 구축 가이드

로그인 없이 닉네임으로 작성 가능한 자체 댓글 시스템을 Cloudflare Worker와 D1으로 직접 구축하는 방법을 상세히 알아봅니다. 관리 기능과 보안까지 고려한 가이드입니다.

시리즈AI로 블로그 만들기2 / 2

  1. 1AI로 블로그 만들기: 워드프레스 대신 Astro+Cloudflare를 택한 이유
  2. 2서버 없이 직접 만든 댓글 시스템: Cloudflare Worker+D1 구축 가이드지금 읽는 글
글자 크기

직접 만든 댓글 시스템, 왜 필요할까?

블로그나 개인 웹사이트를 운영하다 보면 방문자와 소통하고 싶은 니즈가 생기기 마련입니다. 하지만 외부 댓글 서비스를 사용하자니 데이터 종속성이나 광고, 개인 정보 처리 문제 등이 마음에 걸릴 때가 있습니다. 이럴 때 ‘직접 만든 댓글 시스템’은 좋은 대안이 될 수 있습니다. 특히 서버리스(Serverless) 아키텍처를 활용하면 운영 부담을 최소화하면서도 나만의 기능을 구현할 수 있습니다.

Cloudflare Worker와 D1으로 구축하는 서버리스 댓글 시스템

Cloudflare Worker는 서버를 프로비저닝하거나 관리할 필요 없이 전 세계 엣지 네트워크에서 코드를 실행할 수 있게 해주는 서버리스 플랫폼입니다. 여기에 Cloudflare D1은 SQLite 기반의 서버리스 데이터베이스로, Worker와 결합하여 강력하고 비용 효율적인 백엔드를 구축할 수 있습니다. 이 둘을 활용하면 로그인 없이 닉네임만으로 댓글을 작성하고, 관리할 수 있는 자체 댓글 시스템을 만들 수 있습니다.

1. Cloudflare D1 데이터베이스 설정

가장 먼저 댓글 데이터를 저장할 D1 데이터베이스를 생성해야 합니다. Cloudflare 대시보드 또는 Wrangler CLI를 통해 쉽게 만들 수 있습니다.

npx wrangler d1 create my-comment-db

데이터베이스가 생성되면, 댓글 정보를 저장할 테이블 스키마를 정의합니다. 일반적으로 댓글 내용, 작성자 닉네임, 작성 시간, 비밀번호(수정/삭제용), 게시글 ID 등이 필요합니다.

CREATE TABLE comments (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    post_id TEXT NOT NULL,
    author TEXT NOT NULL,
    content TEXT NOT NULL,
    password TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

2. Cloudflare Worker 개발: 댓글 API 구현

이제 Cloudflare Worker를 이용해 댓글을 추가하고, 조회하며, 수정/삭제하는 API 엔드포인트를 구현합니다. Worker는 JavaScript 또는 TypeScript로 작성할 수 있습니다.

댓글 추가 (POST /api/comments)

사용자가 닉네임과 댓글 내용, 그리고 수정/삭제용 비밀번호를 입력하면 D1 데이터베이스에 저장합니다. 비밀번호는 반드시 해싱(Hashing)하여 저장해야 보안을 강화할 수 있습니다.

// 예시 코드 (실제 구현 시 비밀번호 해싱 및 유효성 검사 필요)
export default {
  async fetch(request, env, ctx) {
    if (request.method === 'POST' && request.url.endsWith('/api/comments')) {
      const { postId, author, content, password } = await request.json();
      // 비밀번호 해싱 로직 추가 (예: bcryptjs-wasm)
      const hashedPassword = await hashPassword(password); 

      await env.DB.prepare(
        'INSERT INTO comments (post_id, author, content, password) VALUES (?, ?, ?, ?)'
      )
      .bind(postId, author, content, hashedPassword)
      .run();

      return new Response('Comment added successfully', { status: 201 });
    }
    // ... 다른 API 핸들러
  },
};

댓글 조회 (GET /api/comments/
)

특정 게시글 ID에 해당하는 댓글 목록을 D1에서 조회하여 반환합니다. 최신 댓글이 먼저 보이도록 정렬하는 것이 일반적입니다.

// 예시 코드
if (request.method === 'GET' && request.url.includes('/api/comments/')) {
  const postId = request.url.split('/').pop();
  const { results } = await env.DB.prepare(
    'SELECT id, author, content, created_at FROM comments WHERE post_id = ? ORDER BY created_at DESC'
  )
  .bind(postId)
  .all();

  return new Response(JSON.stringify(results), { 
    headers: { 'Content-Type': 'application/json' }
  });
}

댓글 수정 및 삭제 (PUT/DELETE /api/comments/
)

댓글 작성 시 입력했던 비밀번호를 확인하여 본인 확인 후 수정 또는 삭제를 진행합니다. 비밀번호 비교 시에는 저장된 해시 값과 입력된 비밀번호를 비교해야 합니다.

3. 관리자 기능 및 보안 강화

단순한 댓글 기능 외에 몇 가지 관리자 기능과 보안 장치를 추가하면 시스템의 안정성과 유용성을 높일 수 있습니다.

관리자 비밀번호 및 인증

댓글을 일괄 삭제하거나 특정 댓글을 강제로 수정해야 할 경우를 대비해 관리자용 비밀번호 또는 토큰 기반 인증을 구현할 수 있습니다. 이는 별도의 Worker 엔드포인트로 분리하거나 기존 Worker 내에 미들웨어 형태로 추가할 수 있습니다.

CAPTCHA 또는 Rate Limiting

스팸 댓글이나 악의적인 요청을 방지하기 위해 CAPTCHA(예: Cloudflare Turnstile)를 연동하거나, IP 주소 기반의 Rate Limiting을 적용할 수 있습니다. Cloudflare Workers는 자체적으로 Rate Limiting 기능을 제공하거나, 외부 서비스를 쉽게 통합할 수 있습니다.

프론트엔드 연동 및 배포

백엔드 API가 완성되었다면, 이제 블로그나 웹사이트의 프론트엔드에서 이 API를 호출하여 댓글 UI를 구현할 차례입니다. JavaScript Fetch API를 사용하거나 Axios 같은 라이브러리를 활용하여 Worker 엔드포인트와 통신할 수 있습니다.

Cloudflare Worker는 Wrangler CLI를 통해 wrangler deploy 명령어로 쉽게 배포할 수 있습니다. 배포 후에는 사용자 정의 도메인을 연결하여 깔끔한 엔드포인트를 사용할 수 있습니다.

결론: 나만의 댓글 시스템으로 얻는 자유로움

Cloudflare Worker와 D1을 활용하여 직접 댓글 시스템을 구축하는 과정은 다소 번거로울 수 있지만, 그만큼 높은 자유도와 통제권을 얻을 수 있습니다. 원하는 기능을 마음껏 추가하고, 블로그의 디자인과 완벽하게 통합하며, 데이터의 주인이 될 수 있다는 점은 큰 장점입니다. 서버리스 아키텍처 덕분에 운영 비용도 매우 저렴하게 유지할 수 있습니다.

반응

이어서 읽을 글