요즘은 웬만한 서비스에도 2단계 인증(2FA)을 도입하는 게 기본이 되어가고 있죠. 사용자 보안이 점점 더 중요해지고 있고, 특히 로그인 보안을 강화하려면 OTP(일회용 비밀번호) 같은 기능이 필요합니다. 오늘은 Node.js로 개발할 때 2단계 인증을 간편하게 구현할 수 있게 도와주는 라이브러리인 speakeasy에 대해 알아보려고합니다.
1. speakeasy는 어떤 패키지인가요?
speakeasy는 OTP, 즉 일회용 비밀번호를 생성하고 검증하는 기능을 제공하는 Node.js용 라이브러리예요.
특히 TOTP(Time-based One-Time Password)와 HOTP(HMAC-based One-Time Password) 두 가지 방식을 모두 지원합니다.
보통은 TOTP를 많이 쓰는데요, 이건 사용자의 스마트폰에서 30초마다 새로 생성되는 6자리 숫자 코드 방식입니다. 우리가 흔히 구글 OTP 앱에서 보는 바로 그거예요. speakeasy는 이걸 직접 생성하고 검증하는 로직을 간단하게 만들어줍니다..
2. 설치는 어떻게 하나요?
설치방법은 매우 간단합니다. 터미널에서 다음 명령어만 입력하면 됩니다.
npm install speakeasy
설치가 끝났다면 코드에서 아래와같이 불러올 수 있습니다.:
const speakeasy = require('speakeasy');
3. 2단계 인증 흐름, 어떻게 구현하나요?
3-1. 사용자를 위한 비밀 키 만들기
처음에는 사용자를 위한 고유한 비밀 키(secret)를 생성해줘야 합니다. 이 키는 사용자가 OTP 앱에 등록하게 되는 정보입니다.
const secret = speakeasy.generateSecret({ name: 'MyApp (user@example.com)' });
console.log(secret.base32); // 사용자에게 전달할 비밀 키
console.log(secret.otpauth_url); // QR 코드 생성에 쓰는 URL
3-2. OTP 코드 생성하기
이제 비밀 키를 가지고 OTP를 만들 수 있어요. 이건 서버 측에서 확인용으로 쓰거나 테스트할 때 사용합니다.
const token = speakeasy.totp({
secret: secret.base32,
encoding: 'base32'
});
console.log('OTP:', token);
3-3. 사용자가 입력한 OTP 검증하기
사용자가 로그인하면서 OTP를 입력했을 때, 이걸 서버에서 검증해줘야겠죠?
const isValid = speakeasy.totp.verify({
secret: secret.base32,
encoding: 'base32',
token: userInput, // 사용자가 입력한 코드
window: 1 // 시간 오차 허용 범위
});
console.log(isValid); // true면 인증 성공!
window 값을 주면 시간차(예: 스마트폰 시간이 약간 늦는 경우)를 어느 정도 허용할 수 있어서 더 좋아집니다.
4. QR 코드로 좀 더 편하게
비밀 키를 숫자로 입력하는 건 너무 번거롭잖아요? 그래서 보통은 QR 코드를 띄워서 사용자가 스캔하게 만듭니다. 이때 speakeasy가 만들어주는 otpauth_url을 활용하면 됩니다.
추가로 qrcode라는 패키지를 함께 쓰면 쉽게 이미지로 만들 수 있습니다.
npm install qrcode
const QRCode = require('qrcode');
QRCode.toDataURL(secret.otpauth_url, (err, dataUrl) => {
console.log(dataUrl); // 이걸 <img src="...">로 사용하면 끝!
});