비트베이크

Better Auth로 5분 만에 휴대폰 SMS 인증 구현하기 (Next.js, 서류 제출 ❌)

2026-06-04T01:02:28.656Z

Image related to foundational concepts of web application authentication for developers.

Better Auth로 5분 만에 휴대폰 SMS 인증 구현하기 (Next.js, 서류 제출 ❌)

Next.js나 Express로 사이드 프로젝트나 MVP를 개발할 때, 유저의 신원을 확실히 하기 위해 휴대폰 SMS 본인인증(OTP) 도입을 고민하게 됩니다. 하지만 국내 SMS API 서비스들을 찾아보면 숨이 턱 막히는 상황을 마주하게 됩니다.

> "사업자등록증명원, 통신서비스 가입증명원을 제출하라고요? 전 아직 사업자 없는 1인 개발자인데요?" > "발신번호 사전등록 처리까지 며칠을 기다려야 한다고요?"

스타트업과 개인 개발자에게 시간은 금입니다. 오늘은 차세대 TypeScript 인증 라이브러리인 Better Auth와, 서류 제출 없이 5분 만에 시작할 수 있는 EasyAuth(이지어스) 를 조합하여 빠르고 강력하게 SMS OTP를 구현하는 방법을 소개합니다.

이 글에서 배울 내용

  1. Next.js 등 TS 환경에서 Better Auth 세팅하기
  2. EasyAuth를 활용한 복잡한 서류 없는 SMS 발송 구현
  3. 인증번호 발송(POST /send) 및 검증 API 완성

🛠️ 왜 Better Auth + EasyAuth 인가요?

Better Auth: 차세대 TS Auth 라이브러리

Better Auth는 요즘 개발자들 사이에서 가장 핫한 인증 라이브러리입니다. Auth.js(NextAuth)보다 직관적이고, 플러그인 생태계가 뛰어나며, phoneNumber 플러그인을 통해 손쉽게 SMS OTP 기능을 추가할 수 있습니다.

EasyAuth (이지어스): 개발자를 위한 초간단 SMS API

SMS를 쏘려면 통신사나 기존 벤더를 거쳐야 하지만, 복잡한 과정 없이 즉시 사용할 수 있는 API가 바로 EasyAuth입니다.

  • 서류 불필요: 사업자등록증 등 증빙 서류 없음
  • 즉시 시작: 가입 후 5분 안에 API 연동 완료
  • 자동 발신번호: 대표번호 사전등록 없이 자동 처리
  • 합리적 가격: 건당 15~25원 (기존 30~50원 대비 절반 수준)
  • 무료 체험: 가입 즉시 테스트용 10건 무료 제공

이 완벽한 조합으로 코드를 작성해 봅시다.


💻 단계별 구현 가이드

1. Better Auth 플러그인 설치

먼저 Better Auth를 프로젝트에 설치하고 phoneNumber 플러그인을 추가합니다.

npm install better-auth

2. 서버 측 인증 로직 구현 (auth.ts)

Better Auth의 sendOTP 콜백 내부에 EasyAuth의 POST /send 엔드포인트를 연결합니다. EasyAuth API Key는 대시보드에서 가입 즉시 발급받을 수 있습니다.

// lib/auth.ts
import { betterAuth } from "better-auth";
import { phoneNumber } from "better-auth/plugins";

export const auth = betterAuth({
  plugins: [
    phoneNumber({
      // Better Auth가 인증번호(code)를 자동 생성하여 넘겨줍니다 [1.1.1].
      sendOTP: async ({ phoneNumber, code }, request) => {
        try {
          // EasyAuth API를 호출하여 SMS 발송
          const response = await fetch("https://api.easyauth.kr/send", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              "Authorization": `Bearer ${process.env.EASYAUTH_API_KEY}`,
            },
            body: JSON.stringify({
              to: phoneNumber,
              content: `[내 서비스] 인증번호는 [${code}] 입니다. 3분 내에 입력해주세요.`,
            }),
          });

          if (!response.ok) {
            throw new Error("SMS 발송에 실패했습니다.");
          }
          
          console.log(`${phoneNumber}로 인증번호 발송 완료`);
        } catch (error) {
          console.error("EasyAuth 전송 에러:", error);
          throw error;
        }
      },
    }),
  ],
});

3. 클라이언트 측 검증 로직 구현 (auth-client.ts)

클라이언트용 Better Auth 인스턴스를 생성합니다.

// lib/auth-client.ts
import { createAuthClient } from "better-auth/react";
import { phoneNumberClient } from "better-auth/client/plugins";

export const authClient = createAuthClient({
  plugins: [
    phoneNumberClient()
  ]
});

이제 프론트엔드 UI에서 발송과 검증을 처리하는 완성 코드입니다.

// components/PhoneAuth.tsx
import { useState } from "react";
import { authClient } from "@/lib/auth-client";

export default function PhoneAuth() {
  const [phone, setPhone] = useState("");
  const [otp, setOtp] = useState("");
  const [step, setStep] = useState<"SEND" | "VERIFY">("SEND");

  const handleSendOTP = async () => {
    const { data, error } = await authClient.phoneNumber.sendOtp({
      phoneNumber: phone,
    });
    
    if (error) return alert(error.message);
    setStep("VERIFY");
    alert("인증번호가 발송되었습니다.");
  };

  const handleVerifyOTP = async () => {
    const { data, error } = await authClient.phoneNumber.verify({
      phoneNumber: phone,
      code: otp,
    });

    if (error) return alert(error.message);
    alert("휴대폰 인증이 완료되었습니다!");
    // 이후 가입 혹은 로그인 처리
  };

  return (
    <div>
      <h2>휴대폰 본인인증</h2>
      
      {step === "SEND" ? (
        <div>
           setPhone(e.target.value)} 
          /&gt;
          
            인증번호 받기
          
        </div>
      ) : (
        <div>
           setOtp(e.target.value)} 
          /&gt;
          
            인증하기
          
        </div>
      )}
    </div>
  );
}

💡 Tips & Best Practices

Better Auth 없이 EasyAuth만 독립적으로 사용하고 싶다면?

Better Auth의 세션 관리가 필요 없는 가벼운 프로젝트나, 인증번호 검증 자체를 API에 위임하고 싶다면 EasyAuth가 제공하는 POST /verify 엔드포인트를 활용하세요.

// 1. 발송
await fetch("https://api.easyauth.kr/send", { /* ... */ });

// 2. 검증 (DB 없이 EasyAuth 서버에서 자체 검증)
const verifyRes = await fetch("https://api.easyauth.kr/verify", {
  method: "POST",
  body: JSON.stringify({ to: phone, code: userEnteredCode })
});

상태 관리를 구현할 필요조차 없이 2개의 엔드포인트만으로 완벽한 인증 로직이 완성됩니다.

E.164 전화번호 포맷 준수

국제 표준 포맷(E.164)에 맞춰 전화번호를 전달하는 것이 좋습니다. 010-1234-5678 대신 +821012345678 형태로 클라이언트에서 파싱하여 전송하도록 구성하세요. Better Auth 및 대부분의 SMS 서비스에서 권장하는 방식입니다.


🎯 마무리

과거에는 휴대폰 본인인증을 구현하기 위해 복잡한 절차와 서류 심사, 비싼 도입 비용을 감수해야 했습니다. 하지만 이제 Better Auth의 깔끔한 아키텍처EasyAuth의 개발자 친화적인 API를 결합하면 단 5분 만에 누구나 SMS 인증 시스템을 구축할 수 있습니다.

사이드 프로젝트나 스타트업 MVP를 빠르게 출시해야 하나요? 지금 바로 EasyAuth(이지어스)에 가입하고 무료 제공되는 10건의 크레딧으로 코드를 테스트해보세요. 개발자의 생산성을 깎아먹는 서류 작업은 이제 안녕입니다!

(Tags: Better Auth, Next.js, SMS 인증, TypeScript, EasyAuth, 스타트업 MVP)

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