본문으로 건너뛰기
홈
기술
기술 전체
프로그래밍68
컴퓨터 과학63
AI48
웹 개발36
인프라33
데이터31
소프트웨어 공학18
소개
← 목록으로프로그래밍 › JavaScript › 언어 기능

[JavaScript] 5자리 인증번호 만들기

목차

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() 코드가 동작 원리를 보여주지만, 로그인에 적용할 때는 발급·전달·검증을 모두 서버 책임으로 옮긴다.

참고: Node.js crypto.randomInt API

같은 카테고리의 글