비트베이크

[Next.js App Router] 서버 액션으로 5분 만에 휴대폰 SMS 본인인증 구현하기

2026-05-06T01:02:26.371Z

Professional, modern image illustrating digital authentication concepts for developers, potentially featuring code, security symbols, or user interfaces.

[Next.js App Router] 서버 액션으로 5분 만에 휴대폰 SMS 본인인증 구현하기

사이드 프로젝트나 스타트업 MVP를 개발할 때 꼭 필요한 기능 중 하나가 바로 '휴대폰 SMS 본인인증'입니다. 하지만 막상 기존 통신사나 대형 API 제공업체를 통해 SMS 인증을 붙이려고 하면 큰 벽에 부딪힙니다. 사업자등록증 제출, 통신서비스 이용증명원 발급, 발신번호 사전등록 등 복잡한 서류 작업이 필수이기 때문입니다.

"주말 토이 프로젝트인데 사업자가 어딨어?" 라며 좌절하셨나요? 오늘은 **서류 제출 없이 가입 후 5분 만에 바로 사용할 수 있는 [EasyAuth(이지어스)]**와 Next.js App Router의 Server Actions를 활용하여, 백엔드 서버 구축 없이 초간단하게 SMS 본인인증을 구현하는 방법을 알아봅니다.

왜 Next.js Server Actions인가요?

Next.js의 Server Actions를 사용하면 클라이언트 컴포넌트에서 서버 측 코드를 직접 호출할 수 있습니다. 즉, 별도의 API 라우트(app/api/...)를 만들지 않고도 API 키를 안전하게 숨긴 채로 서드파티 API(EasyAuth)와 통신할 수 있어 개발 생산성이 극대화됩니다.

Step-by-Step 구현 가이드

1. EasyAuth API 구조 이해하기

EasyAuth의 SMS 인증은 단 두 개의 직관적인 엔드포인트로 완성됩니다.

  • POST /send: 인증번호 발송 요청
  • POST /verify: 사용자가 입력한 인증번호 검증

2. 서버 액션(Server Actions) 작성하기

먼저 app/actions.ts 파일을 생성하고 서버 측에서 실행될 로직을 작성합니다. 파일 최상단에 "use server"를 선언하여 서버에서만 실행되도록 보장합니다.

// app/actions.ts
"use server"

const EASYAUTH_API_URL = "https://api.easyauth.co.kr";
const API_KEY = process.env.EASYAUTH_API_KEY;

export async function sendAuthCode(phoneNumber: string) {
  try {
    const response = await fetch(`${EASYAUTH_API_URL}/send`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${API_KEY}`
      },
      body: JSON.stringify({ phone: phoneNumber })
    });
    const data = await response.json();
    return { success: response.ok, data };
  } catch (error) {
    return { success: false, error: "발송 실패" };
  }
}

export async function verifyAuthCode(phoneNumber: string, code: string) {
  try {
    const response = await fetch(`${EASYAUTH_API_URL}/verify`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${API_KEY}`
      },
      body: JSON.stringify({ phone: phoneNumber, code })
    });
    const data = await response.json();
    return { success: response.ok, data };
  } catch (error) {
    return { success: false, error: "검증 실패" };
  }
}

3. 클라이언트 UI 컴포넌트 작성하기

이제 app/page.tsx에 사용자가 전화번호와 인증번호를 입력할 수 있는 UI를 구성합니다.

// app/page.tsx
"use client"

import { useState } from "react";
import { sendAuthCode, verifyAuthCode } from "./actions";

export default function SMSAuthPage() {
  const [phone, setPhone] = useState("");
  const [code, setCode] = useState("");
  const [step, setStep] = useState<1 | 2>(1);
  const [loading, setLoading] = useState(false);

  const handleSendCode = async () => {
    setLoading(true);
    const res = await sendAuthCode(phone);
    setLoading(false);
    
    if (res.success) {
      alert("인증번호가 발송되었습니다.");
      setStep(2);
    } else {
      alert("발송에 실패했습니다.");
    }
  };

  const handleVerifyCode = async () => {
    setLoading(true);
    const res = await verifyAuthCode(phone, code);
    setLoading(false);

    if (res.success) {
      alert("인증이 완료되었습니다!");
      // TODO: 로그인 처리 또는 다음 단계로 이동
    } else {
      alert("잘못된 인증번호입니다.");
    }
  };

  return (
    <div>
      <h1>휴대폰 본인인증</h1>
      
      <div>
        <div>
          전화번호
          <div>
             setPhone(e.target.value)}
              disabled={step === 2}
              className="flex-1 border p-2 rounded"
              placeholder="01012345678"
            /&gt;
            {step === 1 &amp;&amp; (
              
                {loading ? "발송 중..." : "인증번호 발송"}
              
            )}
          </div>
        </div>

        {step === 2 &amp;&amp; (
          <div>
            인증번호
            <div>
               setCode(e.target.value)}
                className="flex-1 border p-2 rounded"
                placeholder="인증번호 6자리"
              /&gt;
              
                {loading ? "확인 중..." : "인증 확인"}
              
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

실무 팁 & 보안 고려사항 (Best Practices)

  1. Rate Limiting (호출 제한): 악의적인 사용자가 SMS 발송 API를 무단 호출하여 요금 폭탄을 맞지 않도록 서버 액션 내부에 Redis 등을 활용한 IP 기반 Rate Limit을 추가하는 것이 좋습니다.
  2. 입력값 검증: Zod와 같은 라이브러리를 사용해 프론트엔드와 서버 액션 모두에서 전화번호 형식 검증을 수행하세요.

결론: 개발자 친화적인 인증 경험

Next.js의 Server Actions와 EasyAuth를 결합하면 별도의 백엔드 구축이나 복잡한 서류 심사 없이 단 5분 만에 완벽한 SMS 본인인증 시스템을 구축할 수 있습니다.

**개발자를 위한 초간단 SMS API, EasyAuth(이지어스)**는 다음과 같은 압도적인 장점이 있습니다:

  • 서류 불필요: 사업자등록증 없이 누구나 즉시 가입 및 사용 가능
  • 자동 발신번호: 귀찮은 대표번호 사전등록 절차 생략
  • 합리적 가격: 건당 15~25원으로 기존(30~50원) 대비 매우 저렴한 유지비용
  • 무료 체험: 가입 즉시 테스트용 10건 무료 제공

더 이상 인증 모듈 붙이느라 소중한 주말 시간을 낭비하지 마세요. 지금 바로 EasyAuth로 여러분의 프로젝트에 빠르고 쉽게 SMS 인증을 추가해 보세요!

Start advertising on Bitbake

Contact Us

More Articles

2026-06-04T01:04:15.823Z

The 2026 E-Commerce New Product Launch Survival Formula: Dominating Platform Search Rankings in 7 Days via Reward-Based Trials and Purchase Verification

2026-06-04T01:04:15.800Z

2026 이커머스 신제품 론칭 생존 공식: 리워드형 체험단과 구매 인증으로 7일 만에 플랫폼 검색 랭킹 장악하기

2026-06-01T01:01:58.264Z

Surviving the 2026 Cookieless Era for B2C: Building Zero-Party Data with Reward-Based Quiz Marketing

2026-06-01T01:01:58.231Z

2026 쿠키리스 시대의 B2C 생존법: 리워드 기반 퀴즈 마케팅으로 제로파티 데이터 구축하기

Services

HomeFeedFAQCustomer Service

Inquiry

Bitbake

LAEM Studio | Business Registration No.: 542-40-01042

4th Floor, 402-J270, 16 Su-ro 116beon-gil, Wabu-eup, Namyangju-si, Gyeonggi-do

TwitterInstagramNaver Blog