[T3 Stack] 서류 없이 5분 만에 Next.js + tRPC SMS 본인인증 구현하기 (1인 개발자 추천)
2026-05-30T01:02:20.456Z
사이드 프로젝트나 MVP를 개발할 때 가장 답답한 순간은 언제일까요? 바로 'SMS 본인인증'을 연동할 때입니다. 국내 대부분의 SMS API 서비스는 사업자등록증과 통신서비스 이용증명원 제출을 필수로 요구합니다. 1인 개발자나 아이디어를 빠르게 테스트해보고 싶은 팀에게는 시작부터 큰 진입장벽이 되죠.
이 글에서는 **서류 없이 5분 만에 연동 가능한 EasyAuth(이지어스)**를 활용하여, 최근 인기 있는 T3 Stack (Next.js + tRPC) 환경에서 SMS 인증을 구현하는 방법을 알아봅니다.
왜 EasyAuth를 선택해야 할까요?
- 서류 전면 면제: 사업자등록증, 이용증명원 없이 즉시 가입 및 사용
- 발신번호 자동 할당: 번호 사전 등록을 위해 통신사를 거칠 필요 없음
- 간결한 구조:
POST /send,POST /verify두 개의 API로 끝 - 합리적인 가격: 건당 15~25원으로 기존(30~50원) 대비 절반 수준, 가입 시 10건 무료 제공
이제 본격적으로 T3 Stack에 EasyAuth를 붙여보겠습니다.
1. tRPC 라우터 설정 (Backend)
T3 Stack에서는 별도의 API 라우트를 만들 필요 없이 tRPC의 Mutation을 사용합니다. 서버의 인증 로직을 담당할 src/server/api/routers/sms.ts 파일을 생성합니다.
import { z } from "zod";
import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";
// EasyAuth API URL 설정
const EASYAUTH_API_URL = "https://api.easyauth.co.kr";
const API_KEY = process.env.EASYAUTH_API_KEY!;
export const smsRouter = createTRPCRouter({
// 1. 인증번호 발송 (Send)
sendOtp: publicProcedure
.input(z.object({ phoneNumber: z.string().min(10) }))
.mutation(async ({ input }) => {
const response = await fetch(`${EASYAUTH_API_URL}/send`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`,
},
body: JSON.stringify({ to: input.phoneNumber }),
});
if (!response.ok) throw new Error("SMS 발송에 실패했습니다.");
return { success: true, message: "인증번호가 발송되었습니다." };
}),
// 2. 인증번호 검증 (Verify)
verifyOtp: publicProcedure
.input(z.object({
phoneNumber: z.string(),
code: z.string().length(6)
}))
.mutation(async ({ input }) => {
const response = await fetch(`${EASYAUTH_API_URL}/verify`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`,
},
body: JSON.stringify({
to: input.phoneNumber,
code: input.code
}),
});
if (!response.ok) throw new Error("인증번호가 일치하지 않습니다.");
return { success: true, message: "인증이 완료되었습니다." };
}),
});
작성한 라우터를 src/server/api/root.ts의 메인 라우터에 추가해줍니다.
2. 프론트엔드 연동 (Frontend)
이제 Next.js 클라이언트 컴포넌트에서 tRPC 훅을 이용해 UI를 구성합니다. 상태 관리는 React의 기본 Hook을 사용했습니다.
import { useState } from "react";
import { api } from "~/utils/api";
export default function SmsAuth() {
const [phoneNumber, setPhoneNumber] = useState("");
const [code, setCode] = useState("");
const [isSent, setIsSent] = useState(false);
const sendOtpMutation = api.sms.sendOtp.useMutation({
onSuccess: () => setIsSent(true),
onError: (err) => alert(err.message),
});
const verifyOtpMutation = api.sms.verifyOtp.useMutation({
onSuccess: () => alert("본인인증 성공!"),
onError: (err) => alert(err.message),
});
const handleSend = () => sendOtpMutation.mutate({ phoneNumber });
const handleVerify = () => verifyOtpMutation.mutate({ phoneNumber, code });
return (
<div>
<h2>휴대폰 본인인증</h2>
<div>
setPhoneNumber(e.target.value)}
disabled={isSent}
className="flex-1 border p-2 rounded"
/>
{isSent ? "재발송" : "인증번호 받기"}
</div>
{isSent && (
<div>
setCode(e.target.value)}
className="flex-1 border p-2 rounded"
/>
확인
</div>
)}
</div>
);
}
마치며
복잡한 서류 작업이나 통신사 심사 없이, 단 2개의 API (/send, /verify)와 T3 Stack의 결합으로 순식간에 SMS 본인인증을 구현해보았습니다. 데이터베이스에 인증번호를 저장하고 만료 시간을 체크하는 등의 귀찮은 백엔드 로직조차 EasyAuth API가 모두 알아서 처리해줍니다.
토이 프로젝트나 MVP 개발을 진행 중이라면, **서류 없이 5분 만에 시작할 수 있는 EasyAuth(이지어스)**를 도입해보세요. 가입 즉시 테스트 가능한 10건의 무료 크레딧이 제공되며, 이후에도 건당 15~25원의 비용으로 서비스 유지가 가능합니다. 지금 바로 경험해보세요!
비트베이크에서 광고를 시작해보세요
광고 문의하기