서류 없이 5분 만에 Next.js SMS 휴대폰 본인인증 구현하기
사이드 프로젝트에 SMS 인증을 붙이려다 좌절한 적 있으신가요?
사이드 프로젝트나 MVP를 개발할 때, 어뷰징을 막거나 실제 유저를 식별하기 위해 휴대폰 본인인증이 필요한 순간이 옵니다. '간단하게 SMS API 하나 붙여야지' 하고 기존 서비스들을 찾아보면 숨이 턱 막힙니다.
- 사업자등록증 제출
- 통신서비스 이용증명원 발급
- 발신번호 사전등록 심사
'나는 아직 사업자도 없는 1인 개발자인데?'
이런 복잡한 절차 때문에 결국 이메일 인증으로 타협한 경험, 다들 한 번쯤 있으실 겁니다.
오늘은 서류 제출이나 복잡한 심사 없이, 개발자를 위한 초간단 SMS 인증 API인 **EasyAuth(이지어스)**를 활용하여 Next.js(App Router) 환경에서 단 5분 만에 SMS 인증을 구현하는 방법을 알아봅니다.
전체 구현 요약
우리는 Next.js의 Route Handlers를 이용해 안전하게 API 요청을 처리하고, 클라이언트 컴포넌트에서 인증 UI를 구현할 것입니다. EasyAuth는 단 두 개의 엔드포인트(/send, /verify)만으로 구성되어 있어 코드가 매우 직관적입니다.
1. 환경 변수 설정
먼저 프로젝트 루트의 .env.local 파일에 API 키를 설정합니다.
EASYAUTH_API_KEY=your_api_key_here
2. Next.js 백엔드 API 구현 (Route Handlers)
Next.js의 백엔드 환경에서 EasyAuth API를 호출합니다. 클라이언트에서 API 키가 직접 노출되지 않도록 하는 보안상 중요한 단계입니다.
인증번호 발송 API (app/api/auth/send/route.ts)
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
try {
const { phone } = await request.json();
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({ phone })
});
if (!response.ok) throw new Error('발송 실패');
return NextResponse.json({ success: true });
} 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 { phone, code } = await request.json();
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({ phone, code })
});
if (!response.ok) throw new Error('검증 실패');
return NextResponse.json({ success: true });
} catch (error) {
return NextResponse.json({ error: '잘못된 인증번호입니다.' }, { status: 400 });
}
}
3. 클라이언트 UI 구현 (프론트엔드)
이제 사용자가 번호를 입력하고 인증번호를 확인할 수 있는 UI 컴포넌트를 만듭니다.
'use client';
import { useState } from 'react';
export default function SmsVerification() {
const [phone, setPhone] = useState('');
const [code, setCode] = useState('');
const [isSent, setIsSent] = useState(false);
const [isVerified, setIsVerified] = useState(false);
const handleSendCode = async () => {
const res = await fetch('/api/auth/send', {
method: 'POST',
body: JSON.stringify({ phone }),
});
if (res.ok) {
setIsSent(true);
alert('인증번호가 발송되었습니다.');
} else {
alert('발송에 실패했습니다.');
}
};
const handleVerifyCode = async () => {
const res = await fetch('/api/auth/verify', {
method: 'POST',
body: JSON.stringify({ phone, code }),
});
if (res.ok) {
setIsVerified(true);
alert('인증이 완료되었습니다!');
} else {
alert('인증번호가 일치하지 않습니다.');
}
};
return (
<div>
<h2>휴대폰 인증</h2>
<div>
setPhone(e.target.value)}
placeholder="휴대폰 번호 (- 없이 입력)"
className="flex-1 border p-2 rounded"
disabled={isVerified}
/>
{isSent ? '재전송' : '인증번호 발송'}
</div>
{isSent && !isVerified && (
<div>
setCode(e.target.value)}
placeholder="인증번호 6자리"
className="flex-1 border p-2 rounded"
/>
확인
</div>
)}
</div>
);
}
실무 팁 & 보안 고려사항 (Tips & Best Practices)
-
클라이언트 유효성 검사 (Validation)
서버로 API를 보내기 전, 정규식을 사용하여 올바른 형태의 휴대폰 번호인지(예:^010\\d{8}$) 미리 확인하면 불필요한 API 호출 비용을 절약할 수 있습니다. -
발송 쿨타임 (Rate Limiting)
악의적인 사용자가 '인증번호 발송' 버튼을 연타하여 요금 폭탄을 유발하지 않도록, 한 번 발송 후 1~3분 간의 타이머를 두어 재발송을 제한하는 것이 좋습니다. -
서버 사이드 API Key 보안
process.env.EASYAUTH_API_KEY는 반드시 서버 측(Route Handlers, Server Actions 등)에서만 사용해야 합니다. 클라이언트 번들(NEXT_PUBLIC_...)에 포함시키지 마세요.
마무리: 왜 EasyAuth인가요?
단 5분, 코드 몇 줄만으로 Next.js에서 완벽한 SMS 본인인증을 구현해 보았습니다.
사이드 프로젝트, 1인 개발, 스타트업의 MVP 테스트에서 기존의 무겁고 복잡한 인증 절차는 큰 허들입니다.
**EasyAuth(이지어스)**는 개발자의 이런 고충을 해결하기 위해 만들어졌습니다.
- 🚫 서류 제출 제로: 사업자등록증 없이 개인 개발자도 즉시 사용 가능
- ⚡ 자동 발신번호: 번거로운 사전등록 없이 바로 발송
- 💰 합리적 가격: 건당 15
25원으로 기존 3050원 대비 저렴
지금 EasyAuth에 가입하시면 즉시 테스트해 볼 수 있는 10건의 무료 크레딧이 제공됩니다. 귀찮은 서류 작업에 시간 낭비하지 말고, 핵심 비즈니스 로직 개발에 집중하세요!