Using Speakeasy for generating one time password - OTP
Today, unfortunately, a strong password alone can’t guarantee enough security for all our accounts.
Two-factor authentication (2FA) or two-step authentication is a security feature that requires two things to verify your identity. Something we not always tend to know — password, and secondary method such as a verification code or token. Its therefore more secure that using a password alone(single-factor authentication).
One-time passwords are usually sent to a user’s email or phone and are usually time-limited and because they can be accessed by someone with your phone they are less secure.
On the other hand Authenticator apps are more secure since they are only linked to one device. To use this we need to use an authenticator app(Google authenticator) and connect to it by entering the linking code or scanning QR code.
Prerequisites
· Nodejs installed on your machine
· Text editor
· Chrome browser
· Postman
Introduction
This tutorial will take you through establishing 2FA on a node.js basic application.
We will be using npm package speakeasy which is a one-time passcode generator, ideal for use in two-factor authentication, that supports Google Authenticator and other two-factor devices. To install we use
npm i speakeasynpm i qrcode // for qrcode
For this example we will be using node-json-db
as our local database and uuid
to create random unique identifiers for our entries.
Implementation
This is a 3 step process
- Generate a secret
- Show a QR code or token for the user to scan in
- Authenticate the token for the first time
Generate a Key
const speakeasy = require('speakeasy')const QRCode = require('qrcode')// generate a secret key
var temp_secret = speakeasy.generateSecret();
To generate QR Code we use the npm qrcode
which has the method toDataURL()
and push it to our db.
// generate a QR Code
const qrcode = await QRCode.toDataURL(temp_secret.otpauth_url)db.push(path, { id: id, temp_secret, data_url: qrcode });
Output
Verifying a token
For this case we will be using postman and sending the token from Google authenticator and the userID as the body of the request
. We manually enter the temp_secret key to get a time based token.
In the POST
request api/verify
:
const {token, userId} = req.body // get body of requestconst path = `/user/${userId}`// get user with the id from the pathconst user = db.getData(path)// Generate a time-based token based on the base-32 key.
const { base32: secret} = user.temp_secretconst verified = speakeasy.totp({
secret,
encoding: 'base32',
token});
Output
The entire code can be found my Github or on the gist
Conclusion
You have just learnt how to setup second factor authentication to your web applications with time-based-one passwords.
Now that you have secret tokens being generated, why not implement your own application for generating TOTP tokens?🦸♂️