Node.js를 이용해서 OTP 인증 구현하기_OTP 인증 구현하기

이애옹·2023년 10월 16일
0
post-thumbnail

회사 프로그램에 로그인 하기 위해서 인증 방식을 선택할 수 있도록 되어있는데, 그 중 OTP 인증 방식이 있어서 정리해봄!!!

일단 OTP에 대해서 알아보자!!

📌 OTP의 의미

OTP란, One Time Password의 약자로, 일회용 비밀번호 생성기를 말한다. 이는 고정된 패스워드 대신 무작위로 생성되는 일회용 패스워드로 사용자를 인증하는 방식이다. 한번 사용하고 난 패스워드는 폐기되어 재사용이 불가능하다.

📌 OTP를 사용하는 이유

OTP를 사용하는 가장 큰 이유는 보안 때문이다. 일반적인 아이디/패스워드를 사용하는 인증 기법의 경우 패스워드 노출이 가장 우려되는 사항인데, 매번 같은 방식으로 패스워드를 사용하다 보면 해킹이나 추측등으로 유출이 될 수 있다.

OTP는 이와 같은 취약성을 보완하여 보안을 강화하기 위해 도입되었다. 로그인할때마다 서로 다른 패스워드를 이용함에 따라 패스워드 노출을 최소화 하고 보안을 강화한다.

출처 : 한국정보통신기술협회_ 생활 속 표준 - 금융사기 피해 방지, 일회용 패스워드(OTP)로

📌 TOTP (Time-based One-Time Password) 란?

현재 많이 사용되고 있는 Google OTP, 은행 OTP는 대부분 TOTP 기반으로 동작되고 있다. 이 외에도 HOTP 기반 동작 방식이 있지만 이건 나중에 정리 ..

TOTP는 HOTP 기반으로 나왔으며, HOTP와 다르게 시간(Time) 기반 이라는 특징이 있다.

TOTP는 처음 바코드나 일정 길이의 문자열이 secretKey가 된다. 따라서 이 키를 저장해두면 OTP를 잃어버려도 복구가 가능하다.

또한, TOTP는 특정 시간 마다 다음 값으로 변경된다. 다만 클라이언트와 서버의 시간 차이 때문에 인증이 제대로 되지 않는 경우가 있는데 이럴 경우 기기의 시간이 현재 시간과 일치한지 확인 후 일치하지 않다면 시간 동기화가 필요하다.

이번에 작성할 글에서 사용하는 인증 방식도 TOTP 기반 인증 방식이다!!!

📌 OTP 인증 구현하기

📝 모듈 설치하기

일단 필요한 모듈을 설치 해 줘야 하는데, 총 2개의 모듈을 설치 해 줄 것이다.

npm install --save speakeasy
npm install --save qrcode

일단 여기서 qrcode는 말그대로 QR코드를 생성하는 모듈이다.

speakeasy는 좀 생소 할 수 있는데, 해당 모듈에 대한 설명은 다음과 같다.

"speakeasy"는 Node.js에서 사용할 수 있는 오픈 소스 모듈 중 하나로, 2단계 인증(2FA)을 구현하기 위한 도구로 널리 사용됩니다. 이 모듈을 사용하면 웹 애플리케이션에서 토큰 기반의 2단계 인증을 간단하게 구현할 수 있습니다.


주로 Time-based One-Time Passwords (TOTP)와 HMAC-based One-Time Passwords (HOTP)를 생성하고 검증하는 데 사용됩니다. 이러한 암호화된 비밀번호들은 일반적으로 QR 코드를 통해 사용자의 스마트폰 앱(예: Google Authenticator, Authy)에 등록됩니다.

📝 QR코드 생성하기

이제 본격적으로 QR 코드를 생성해야한다.

speakeasy 모듈을 이용해 생성한 시크릿키를 기반으로 QR을 생성해야 하기 때문에, 일단 시크릿키를 먼저 생성 하고 -> 해당 시크릿 키로 QR코드용 URL 생성 -> 생성된 URL을 기반으로 QR코드 생성 단계로 진행하면 된다.


const speakeasy = require('speakeasy');
const QRcode = require('qrcode');

const secret = speakeasy.generateSecret({
   length: 20, // 비밀키의 길이를 설정 (20자리)
   name: userId, // 사용자 아이디를 비밀키의 이름으로 설정
   algorithm: 'sha512' // 해시 알고리즘 지정 (SHA-512 사용)
})
        
var url = speakeasy.otpauthURL({
   secret: secret.ascii, // OTP 인증을 위한 비밀키 (ASCII 형식)
   issuer: 'OTP TEST', // 발급자(issuer) 정보 설정
   label: userId, // 사용자 아이디를 라벨로 사용하여 OTP의 라벨 설정
   algorithm: 'sha512' // 해시 알고리즘 지정 (SHA-512 사용)
})
                
QRcode.toDataURL(url, function(err, imageData) {  
   loginResult.imageData = imageData; // QR 코드 이미지 데이터 추가
   loginResult.code = 'S03'; // 로그인 결과 코드 설정
   loginResult.secret = secret.base32; // 생성된 비밀키(base32 형식) 추가

   // HTTP 응답으로 loginResult 객체를 전송
   res.send(loginResult);
});

speakeasy.generateSecret() : generateSecret 메서드를 이용하여 비밀키 생성

speakeasy.otpauthURL() : otpauthURL 메서드를 이용하여 OTP의 인증 UTL 생성

QRcode.toDataURL() : QR 코드를 생성하고 생성된 이미지를 객체에 추가하여 전송

여기서 생성된 imageData를 HTML에서 img 태그에 넣어주면 QR코드로 띄워줄 수 있다!!

img 태그가 있는 코드를 만들어주고 거기에 저 데이터 넘겨주면 된다~

인터넷에 검색하면 QR 코드 생성 해 주는 웹 사이트 있으니까 거기서 테스트를 먼저 해 보는것도 좋을 것 같다!!

하여튼 여기까지 해 주면 OTP용 QR을 생성 해 줄 수 있다!

QR 생성까지는 완료됐고, 다음 글에서는 생성된 QR로 검증을 하는 방법과 관련 에러에 대해 작성해봐야겠다~~~

👀 참고자료

profile
안녕하세요

0개의 댓글