목차
0~9까지 다섯자리 인증번호 만들기
아래 Math.random() 예제는 화면에 임의의 숫자를 보여 주는 옛 데모다. 실제 로그인·본인 확인용 인증번호는 브라우저에서 생성하거나 검증하면 안 된다. 사용자가 개발자 도구로 값을 읽거나 바꿀 수 있기 때문이다.
javaScript 소스
rand.js
var randomNum = {};
//0~9까지의 난수
randomNum.random = function(n1, n2) {
return parseInt(Math.random() * (n2 -n1 +1)) + n1;
};
//인증번호를 뽑을 난수 입력 n 5이면 5자리
randomNum.authNo= function(n) {
var value = "";
for(var i=0; i<n; i++){
value += randomNum.random(0,9);
}
return value;
};
//화면에 번호 출력
randomNum.printRandom =function(data,num) {
document.getElementById(data).innerHTML = randomNum.authNo(num);
};
html소스
rand.html
<script type="text/javascript">
function refresh() {
location.reload();
}
</script>
</head>
<body onload="randomNum.printRandom('auth', 5)">
<p>
고객님의 인증번호는 <span id="auth">00000</span> 입니다.
</p>
<input type="button" value="인증번호 새로 받기" onclick="refresh()"/>
</body>
결과

실제 인증 흐름
flowchart LR 요청[사용자가 발급 요청] --> 서버[서버: 암호학적 난수 생성] 서버 --> 저장[만료 시각·시도 횟수와 함께 저장] 서버 --> 전달[메일·문자 등 별도 채널로 전달] 입력[사용자가 코드 입력] --> 검증[서버: 만료·횟수·값 검증] 저장 --> 검증
서버에서는 암호학적 난수 API를 사용한다. 예를 들어 Node.js라면 다음처럼 문자열로 만들면 맨 앞의 0도 유지된다.
import { randomInt } from 'node:crypto';
const code = Array.from({ length: 5 }, () => randomInt(0, 10)).join('');
이 코드는 생성 부분만 보여 준다. 실제 서비스에서는 코드 자체를 응답으로 돌려주지 않고, 만료 시간·재발급 제한·검증 시도 제한·사용 후 폐기를 서버에서 구현해야 한다. 다섯 자리 숫자는 가능한 값이 적으므로 시도 제한 없이 인증 수단으로 쓰면 위험하다.
5자리 값의 한계와 서버 검증
숫자 다섯 자리는 00000부터 99999까지 100,000가지다. 앞자리가 0일 수 있으므로 정수보다 문자열로 보관한다. 보안용 난수로 발급하더라도 전체 후보 수가 작아 시도 횟수를 제한하지 않으면 추측할 수 있다. 서버는 사용자·용도·만료 시각에 발급 기록을 묶고, 성공하면 즉시 사용 처리하며, 연속 실패와 재발급에 한도를 둔다. 재발급한 이전 코드를 여전히 허용할지도 정책으로 결정한다.
// 서버 내부의 검증 로직을 설명하는 의사 코드
function verifyCode(record, submitted, now) {
if (!record || record.used || now >= record.expiresAt) return false;
if (record.attempts >= 5) return false;
record.attempts += 1; // 실제 구현에서는 저장소에서 원자적으로 갱신
if (!matchesStoredCode(record, submitted)) return false;
record.used = true; // 성공 상태도 원자적으로 저장
return true;
}
이 예제의 matchesStoredCode는 서버에 별도로 구현할 비교 함수이며 전체 인증 시스템이 아니다. 실제 저장소에서는 동시에 두 요청이 와도 한 번만 성공하도록 시도 횟수 증가와 사용 처리에 원자적 갱신이 필요하다. 민감한 인증 코드를 평문 로그에 남기거나 브라우저로 다시 돌려주면 안 된다. 단순 화면 데모라면 기존 Math.random() 코드가 동작 원리를 보여주지만, 로그인에 적용할 때는 발급·전달·검증을 모두 서버 책임으로 옮긴다.