[Next.js] 서류 없이 5분 만에 SMS 본인인증 구현하기 (App Router)
서론: SMS 인증, 개발보다 서류 준비가 더 힘들다고요?
사이드 프로젝트나 스타트업의 MVP를 개발할 때, 스팸 가입을 막고 진성 유저를 확보하기 위해 '휴대폰 본인인증(SMS OTP)'은 필수적인 기능입니다.
하지만 막상 기존 SMS API 제공업체들을 찾아보면 숨이 턱 막힙니다. 사업자등록증, 통신서비스 이용증명원 등 복잡한 서류 제출은 기본이고, 스팸 방지를 명목으로 발신번호 사전등록까지 마쳐야 비로소 API를 테스트해 볼 수 있죠. 이제 막 아이디어를 코드로 옮기는 1인 개발자나 토이 프로젝트 팀에게 이런 행정 절차는 너무나 큰 진입장벽입니다.
"그냥 깔끔하게 API 키만 발급받아서 바로 연동할 수는 없을까?"
이런 고민을 하셨다면, 오늘 소개할 튜토리얼이 완벽한 해결책이 될 것입니다. 이 글에서는 서류 제출과 발신번호 등록 없이 가입 후 5분 만에 Next.js 환경에서 SMS 인증을 구현하는 방법을 알아봅니다.
솔루션 요약: 개발자를 위한 초간단 SMS API, EasyAuth
이 튜토리얼에서는 개발자 친화적인 SMS 인증 서비스인 **EasyAuth(이지어스)**를 사용합니다.
EasyAuth는 다음과 같은 강력한 장점이 있습니다:
- 완전 무서류: 사업자등록증 등 일체의 서류 제출 불필요
- 즉시 시작: 자동 발신번호 할당으로 사전등록 없이 즉시 발송 가능
- 합리적인 가격: 기존 업체 대비 절반 수준인 건당 15~25원 (가입 시 10건 무료 제공)
- 심플한 API:
POST /send(발송)와POST /verify(검증) 단 두 개의 엔드포인트
이제 Next.js 14+ (App Router) 환경에서 이 API를 어떻게 연동하는지 단계별로 살펴보겠습니다.
1단계: Next.js Route Handlers 설정 (백엔드)
먼저 클라이언트에서 API 키가 노출되지 않도록 서버 사이드(Route Handlers)에서 EasyAuth API와 통신하는 프록시 API를 만듭니다.
인증번호 발송 API (app/api/auth/send/route.ts)
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
try {
const { phoneNumber } = await request.json();
// EasyAuth API 호출
const response = await fetch('https://api.easyauth.co.kr/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.EASYAUTH_API_KEY}`
},
body: JSON.stringify({ to: phoneNumber })
});
const data = await response.json();
if (!response.ok) {
return NextResponse.json({ error: data.message }, { status: response.status });
}
return NextResponse.json({ success: true, message: '인증번호가 발송되었습니다.' });
} catch (error) {
return NextResponse.json({ error: '서버 에러가 발생했습니다.' }, { status: 500 });
}
}
인증번호 검증 API (app/api/auth/verify/route.ts)
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
try {
const { phoneNumber, code } = await request.json();
// EasyAuth API 호출
const response = await fetch('https://api.easyauth.co.kr/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.EASYAUTH_API_KEY}`
},
body: JSON.stringify({ to: phoneNumber, code })
});
const data = await response.json();
if (!response.ok) {
return NextResponse.json({ error: '잘못된 인증번호입니다.' }, { status: 400 });
}
return NextResponse.json({ success: true, message: '인증이 완료되었습니다.' });
} catch (error) {
return NextResponse.json({ error: '서버 에러가 발생했습니다.' }, { status: 500 });
}
}
2단계: 프론트엔드 UI 컴포넌트 구현
이제 사용자가 전화번호와 인증번호를 입력할 수 있는 클라이언트 컴포넌트를 만듭니다.
app/page.tsx (또는 해당 로그인 페이지)
'use client';
import { useState } from 'react';
export default function SmsAuth() {
const [phoneNumber, setPhoneNumber] = useState('');
const [code, setCode] = useState('');
const [step, setStep] = useState<'SEND' | 'VERIFY'>('SEND');
const [message, setMessage] = useState('');
const handleSend = async () => {
setMessage('');
const res = await fetch('/api/auth/send', {
method: 'POST',
body: JSON.stringify({ phoneNumber }),
});
if (res.ok) {
setStep('VERIFY');
setMessage('인증번호 6자리가 발송되었습니다.');
} else {
const error = await res.json();
setMessage(error.error || '발송 실패');
}
};
const handleVerify = async () => {
setMessage('');
const res = await fetch('/api/auth/verify', {
method: 'POST',
body: JSON.stringify({ phoneNumber, code }),
});
if (res.ok) {
setMessage('✅ 본인인증이 완료되었습니다!');
// 이후 회원가입/로그인 로직 진행
} else {
setMessage('❌ 인증번호가 일치하지 않습니다.');
}
};
return (
<div>
<h2>휴대폰 본인인증</h2>
<div>
<div>
setPhoneNumber(e.target.value)}
disabled={step === 'VERIFY'}
className="w-full p-3 border rounded"
/>
{step === 'SEND' && (
인증번호 받기
)}
</div>
{step === 'VERIFY' && (
<div>
setCode(e.target.value)}
className="w-full p-3 border rounded"
/>
인증 확인
</div>
)}
{message && <p>{message}</p>}
</div>
</div>
);
}
실무 팁 및 모범 사례 (Best Practices)
- 보안 및 환경 변수:
반드시EASYAUTH_API_KEY는.env.local파일에 저장하고 프론트엔드(NEXT_PUBLIC_접두사)에 노출하지 않아야 합니다. 인증 로직은 반드시 서버 사이드(Route Handlers)를 거치게 설계하세요. - Rate Limiting (호출 제한):
악의적인 사용자가 무단으로 SMS 발송 API를 남용하는 것을 막기 위해 Redis나 Upstash를 활용하여 IP당 발송 횟수 제한(Rate Limit)을 적용하는 것을 권장합니다.
결론
복잡한 통신사 서류, 끝없는 심사 대기, 발신번호 등록 절차... 이 모든 것들이 이제는 옛말이 되었습니다. 코드를 복사해서 붙여넣고 환경 변수만 설정하면 Next.js에서 완벽하게 동작하는 SMS OTP 인증 시스템을 구축할 수 있습니다.
스타트업 초기 MVP 단계이거나 혼자서 토이 프로젝트를 만들고 계신가요? **개발자만을 위해 탄생한 초간단 SMS API, EasyAuth(이지어스)**를 도입해 보세요. 가입 즉시 제공되는 10건의 무료 테스트 크레딧과 건당 15원이라는 파격적인 비용으로, 불필요한 행정 업무 없이 개발에만 집중할 수 있습니다.
지금 바로 EasyAuth에서 API 키를 발급받고 5분 만에 본인인증을 완성해 보세요!