[Spring Boot/Kotlin] 서류 없이 5분 만에 완벽한 SMS 휴대폰 인증 구현하기 (feat. Redis)
2026-05-23T01:01:46.782Z

SMS 인증, 시작부터 막히셨나요?
"사이드 프로젝트에 휴대폰 인증을 붙이려고 통신사 API를 찾아봤는데, 사업자등록증과 통신서비스 이용증명원을 내라고요? 전 아직 학생/직장인 개인 개발자인데요?"
개발자들이 토이 프로젝트나 MVP를 개발할 때 가장 먼저 좌절하는 구간이 바로 'SMS 본인인증'입니다. 기존 국내 SMS 서비스들은 가입부터 복잡한 서류 제출을 요구하고, 발신번호 사전등록제 때문에 대표번호를 인증해야 하는 등 진입 장벽이 매우 높습니다.
하지만 걱정하지 마세요. **사업자등록증 등의 서류 없이, 가입 후 5분 만에 바로 사용할 수 있는 EasyAuth(이지어스)**와 Spring Boot, Kotlin, Redis를 활용해 완벽한 SMS OTP 인증 시스템을 구축하는 방법을 알려드립니다.
이 글에서 구현할 아키텍처
우리가 만들 SMS 인증 시스템의 흐름은 다음과 같습니다.
POST /send: 사용자가 휴대폰 번호를 입력하면 서버에서 6자리 난수(OTP)를 생성합니다.- Redis 저장: 생성된 OTP를 휴대폰 번호를 Key로 하여 Redis에 저장합니다. (TTL 3분 설정)
- EasyAuth API 호출: 생성된 OTP를 EasyAuth의 발송 API를 통해 사용자에게 전송합니다.
POST /verify: 사용자가 입력한 인증번호와 Redis에 저장된 값을 비교하여 검증합니다.
1단계: 환경 설정 및 의존성 추가
먼저 Spring Boot 프로젝트의 build.gradle.kts에 Redis와 외부 API 통신을 위한 의존성을 추가합니다.
dependencies {
// Redis
implementation("org.springframework.boot:spring-boot-starter-data-redis")
// Web
implementation("org.springframework.boot:spring-boot-starter-web")
}
application.yml에 Redis 연결 정보를 설정합니다.
spring:
data:
redis:
host: localhost
port: 6379
2단계: SMS 인증 서비스 구현 (Service)
EasyAuth API를 활용해 실제 문자를 발송하고, Redis를 통해 인증번호의 생명주기를 관리하는 핵심 비즈니스 로직입니다.
import org.springframework.data.redis.core.StringRedisTemplate
import org.springframework.stereotype.Service
import org.springframework.web.client.RestTemplate
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import java.util.concurrent.TimeUnit
import kotlin.random.Random
@Service
class SmsAuthService(
private val redisTemplate: StringRedisTemplate
) {
// EasyAuth API 엔드포인트 및 인증 키 (가입 시 즉시 발급)
private val easyAuthUrl = "https://api.easyauth.co.kr/send"
private val apiKey = "YOUR_EASYAUTH_API_KEY"
// 인증번호 만료 시간 (3분)
private val AUTH_TTL = 3L
fun sendCode(phoneNumber: String) {
// 1. 6자리 랜덤 인증번호 생성
val authCode = Random.nextInt(100000, 999999).toString()
// 2. Redis에 저장 (Key: 전화번호, Value: 인증번호)
redisTemplate.opsForValue().set(
"sms:auth:$phoneNumber",
authCode,
AUTH_TTL,
TimeUnit.MINUTES
)
// 3. EasyAuth를 통해 SMS 발송
sendViaEasyAuth(phoneNumber, authCode)
}
fun verifyCode(phoneNumber: String, inputCode: String): Boolean {
val key = "sms:auth:$phoneNumber"
val savedCode = redisTemplate.opsForValue().get(key)
return if (savedCode != null && savedCode == inputCode) {
// 인증 성공 시 Redis에서 해당 키 삭제 (재사용 방지)
redisTemplate.delete(key)
true
} else {
false
}
}
private fun sendViaEasyAuth(phoneNumber: String, code: String) {
val restTemplate = RestTemplate()
val headers = HttpHeaders().apply {
contentType = MediaType.APPLICATION_JSON
set("Authorization", "Bearer $apiKey")
}
val requestBody = mapOf(
"to" to phoneNumber,
"text" to "[내 서비스] 인증번호는 [$code] 입니다. 3분 이내에 입력해주세요."
)
val request = HttpEntity(requestBody, headers)
// EasyAuth API 호출 - 서류 없이 바로 전송됩니다!
restTemplate.postForEntity(easyAuthUrl, request, String::class.java)
}
}
3단계: API 엔드포인트 노출 (Controller)
이제 클라이언트(웹/앱)에서 호출할 수 있도록 Controller를 작성합니다.
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/api/auth")
class SmsAuthController(
private val smsAuthService: SmsAuthService
) {
@PostMapping("/send")
fun sendAuthCode(@RequestBody request: SendRequest): ResponseEntity> {
smsAuthService.sendCode(request.phoneNumber)
return ResponseEntity.ok(mapOf("message" to "인증번호가 발송되었습니다."))
}
@PostMapping("/verify")
fun verifyAuthCode(@RequestBody request: VerifyRequest): ResponseEntity> {
val isValid = smsAuthService.verifyCode(request.phoneNumber, request.code)
return if (isValid) {
ResponseEntity.ok(mapOf("message" to "인증에 성공했습니다."))
} else {
ResponseEntity.status(401).body(mapOf("message" to "인증번호가 일치하지 않거나 만료되었습니다."))
}
}
}
// DTO Classes
data class SendRequest(val phoneNumber: String)
data class VerifyRequest(val phoneNumber: String, val code: String)
실무를 위한 추가 팁 (Best Practices)
위의 코드만으로도 훌륭히 동작하지만, 실제 프로덕션 레벨에서는 다음 사항들을 추가로 고려해야 합니다.
- Rate Limiting (어뷰징 방지) 동일한 번호로 1분에 수십 번씩 발송 요청을 보내는 것을 막아야 합니다. Redis를 활용해 하루 발송 횟수 제한(예: 5회)을 걸어두는 것을 권장합니다.
- 자동 발신번호 세팅 일반적으로 SMS 발송을 위해서는 통신사에 발신번호를 사전 등록해야 합니다. 하지만 EasyAuth를 사용하면 기본 제공되는 자동 발신번호 풀을 통해 별도 등록 없이 즉시 발송이 가능합니다.
마무리: 왜 EasyAuth인가요?
이처럼 Spring Boot와 Redis를 사용하면 로직 자체는 간단하게 구현할 수 있습니다. 하지만 문제는 늘 **'외부 API 연동 조건'**이었습니다.
토이 프로젝트, 스타트업 MVP, 1인 개발자라면 복잡한 심사 과정 없이 즉시 사용할 수 있는 **EasyAuth(이지어스)**를 강력히 추천합니다.
- 서류 Zero: 사업자등록증, 통신서비스 이용증명원 없이 가입 즉시 발급되는 API Key
- 자동 발신번호: 번호 사전등록 심사 대기 불필요
- 합리적인 가격: 기존 30~50원 대비 파격적으로 저렴한 건당 15~25원
- 무료 테스트: 가입 시 10건 무료 제공으로 즉시 로직 테스트 가능
지금 바로 EasyAuth와 함께 서류 더미에서 벗어나, 5분 만에 개발에만 집중해 보세요!
비트베이크에서 광고를 시작해보세요
광고 문의하기