[Hono + Cloudflare] 서류 없이 5분 만에 서버리스 SMS 본인인증 API 만들기

2026년 4월 21일4분 소요

A blog post thumbnail featuring professional, modern, and clean tech visuals, relevant to developer and authentication content, with ample space for text overlay. This image type would be found using the Unsplash search query: 'secure digital authentication'.

사이드 프로젝트에 SMS 인증 붙이려다 포기하신 적 있나요?

React나 Next.js로 멋진 MVP를 만들고 사용자 인증을 추가하려는 순간, 많은 개발자들이 장벽에 부딪힙니다. "간단하게 문자 인증 하나 붙여야지" 하고 API를 찾아보면 사업자등록증 제출, 통신사 가입 증명원, 발신번호 사전등록 등 복잡한 서류 작업이 기다리고 있기 때문입니다. 1인 개발자나 사이드 프로젝트를 진행하는 팀에게는 너무 가혹한 조건이죠.

이 글에서는 **서류 없이 5분 만에 즉시 사용할 수 있는 EasyAuth(이지어스)**와, 무료 서버리스 환경인 Cloudflare Workers + Hono를 결합하여 빠르고 강력한 서버리스 SMS 본인인증 API를 구축하는 방법을 알아봅니다.


이 글에서 배울 내용 (Solution Overview)

  • Cloudflare Workers & Hono: 엣지(Edge) 환경에서 동작하는 초고속, 제로 웨이스트 서버리스 API 구축
  • EasyAuth 연동: 서류 제출 없이 즉시 발송 가능한 SMS API(POST /send, POST /verify) 적용
  • 프론트엔드(Next.js, React 등)에서 즉시 호출할 수 있는 완성된 백엔드 코드 작성

단계별 구현 가이드 (Step-by-Step Implementation)

1. Hono 프로젝트 세팅

Hono는 Cloudflare Workers와 찰떡궁합을 자랑하는 초경량 웹 프레임워크입니다. Express.js와 비슷한 라우팅 시스템을 제공해 러닝 커브가 거의 없습니다.

npm create hono@latest my-sms-api
# 템플릿 선택: cloudflare-workers
cd my-sms-api
npm install

2. 환경 변수 설정 (.dev.vars)

EasyAuth 회원가입 후 발급받은 API Key를 환경변수에 등록합니다. (가입 시 10건이 무료로 제공되니 바로 테스트해볼 수 있습니다!)

프로젝트 루트에 .dev.vars 파일을 생성하고 아래와 같이 입력합니다.

EASYAUTH_API_KEY=your_easyauth_api_key_here

3. 인증번호 발송 API 구현 (POST /send)

이제 src/index.ts 파일을 열어 인증번호 발송 로직을 작성합니다. EasyAuth의 API는 놀랍도록 단순합니다. 번호만 넘기면 알아서 자동 발신번호로 문자가 전송됩니다.

app.post('/api/auth/send', async (c) => {
  const { phone } = await c.req.json();

  const response = await fetch('https://api.easyauth.kr/send', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${c.env.EASYAUTH_API_KEY}`
    },
    body: JSON.stringify({ phone })
  });

  if (!response.ok) return c.json({ error: '발송 실패' }, 500);
  return c.json({ message: '인증번호 발송 완료' });
});

4. 인증번호 검증 API 구현 (POST /verify)

사용자가 입력한 OTP 코드를 검증하는 엔드포인트도 추가합니다.

app.post('/api/auth/verify', async (c) => {
  const { phone, code } = await c.req.json();

  const response = await fetch('https://api.easyauth.kr/verify', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${c.env.EASYAUTH_API_KEY}`
    },
    body: JSON.stringify({ phone, code })
  });

  if (!response.ok) return c.json({ error: '인증 실패' }, 400);
  return c.json({ message: '인증 완료' });
});

전체 동작하는 완성 코드 (Complete Code)

CORS 설정과 타입 정의가 모두 포함된 src/index.ts 전체 코드입니다. 이 코드를 복사해서 바로 배포(npm run deploy)하면 됩니다.

import { Hono } from 'hono';
import { cors } from 'hono/cors';

// 환경변수 타입 정의
type Bindings = {
  EASYAUTH_API_KEY: string;
};

const app = new Hono<{ Bindings: Bindings }>();

// 프론트엔드 연동을 위한 CORS 허용
app.use('/api/*', cors());

// 1. 인증번호 발송
app.post('/api/auth/send', async (c) => {
  try {
    const { phone } = await c.req.json();
    
    const response = await fetch('https://api.easyauth.kr/send', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${c.env.EASYAUTH_API_KEY}`
      },
      body: JSON.stringify({ phone })
    });

    if (!response.ok) throw new Error('발송 API 에러');
    return c.json({ success: true, message: '인증번호가 발송되었습니다.' });
  } catch (error) {
    return c.json({ success: false, error: '서버 에러가 발생했습니다.' }, 500);
  }
});

// 2. 인증번호 검증
app.post('/api/auth/verify', async (c) => {
  try {
    const { phone, code } = await c.req.json();
    
    const response = await fetch('https://api.easyauth.kr/verify', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${c.env.EASYAUTH_API_KEY}`
      },
      body: JSON.stringify({ phone, code })
    });

    if (!response.ok) return c.json({ success: false, error: '유효하지 않은 인증번호입니다.' }, 400);
    return c.json({ success: true, message: '본인인증이 완료되었습니다.' });
  } catch (error) {
    return c.json({ success: false, error: '서버 에러가 발생했습니다.' }, 500);
  }
});

export default app;

실무 적용 팁 (Tips & Best Practices)

  1. 보안 고려사항 (Rate Limiting)
    Cloudflare Workers 환경에서는 악의적인 API 호출을 막기 위해 @upstash/ratelimit 등을 활용해 IP 기반 호출 횟수 제한을 두는 것이 좋습니다.
  2. 비용 최적화
    기존 SMS API들이 건당 3050원을 청구하는 반면, EasyAuth는 건당 1525원의 합리적인 가격을 제공하므로, 토이 프로젝트부터 대규모 서비스까지 부담 없이 스케일업할 수 있습니다.
  3. 클라이언트 에러 처리
    Next.js나 React 프론트엔드에서 이 라우트를 호출할 때, success boolean 값을 기준으로 UI 분기를 처리하면 훨씬 직관적인 UX를 만들 수 있습니다.

결론: 개발자는 개발만 하세요

지금까지 Hono와 Cloudflare Workers를 이용해 초간단 서버리스 SMS 인증 API를 만들어 보았습니다. 서버 인프라 고민은 Cloudflare에, 골치 아픈 통신사 서류 작업은 EasyAuth에 맡기시면 됩니다.

사업자등록증도, 대표번호 사전등록도 필요 없습니다. 가입 후 5분 안에 API 연동을 완료하고 MVP 개발에 집중하세요.

👉 서류 없이 5분 만에 시작할 수 있는 EasyAuth (가입 시 10건 무료!)

SMS 인증을 쉽게 시작하세요

서류 없이 가입 즉시 API Key를 발급받고 바로 시작할 수 있습니다.
건당 25원, 가입 시 10건 무료!