I have created many web applications that uses OTP verification via SMS. It works by sending a 4 to 6 digit number to the user's phone number via SMS. And the user has to enter the OTP in order to verify the phone number.
In most of the cases this is done using a simple technique, by keeping the OTP in the database or memory storage and matching it with the user input. In this article, I will try to explain how we can achieve the same result without any database of sorts.
let's talk about the motivation behind this approach. Database operation is expensive, usually slower and because it relies on another application or service, has a probability to fail. Another good reasons is, OTP is a temporary data. It does not belong to the database.
The technique involves cryptography, in a sense It's quite similar to how JWT tokens are verified. But also very different from JWT because of the way data is handled. This technique is done using the following steps:
Create a cryptographic hash of the phone number, the generated OTP and the expiry timestamp combined.
Append the expiry timestamp with the hash and Send the hash to the user as the response of the first request.
Once the user gets the SMS, the user sends back the hash, the phone number and the OTP in the second request.
The server verifies the OTP by hashing the phone number, OTP sent by the user, and the expiry timestamp that was appended with the hash, the user sent back. Using the same key and same algorithm.
If the expiry timestamp is valid and still in the future. And the newly generated hash matches the one sent by the user. Then the OTP is authentic.
Lot to take in? Let's see it in Action.
The code in this article is also available in NPM
We will create two functions, one for creating the hash and and sending the SMS OTP, another for verifying the OTP.
We will use the awesome package otp-generator to generate OTP codes in NodeJS. you need to install this package using npm or yarn.I've also omitted the
package.json file in the example. Let's take a look at the hash generator code, every line is commented so that they are easy to understand:
This function will return a hash. The hash needs to be sent back to the user as HTTP response. when the user requests for an OTP. the sendSMS function, which is a dummy function in this example. In the real world needs to be implemented depending on the SMS provider's API. This function will send the SMS to the user with the OTP.
Email can be used as well.
The user, once received the OTP, will send the hash that came from the first request, phone number and OTP to the server and the below function will verify it. Let's take a look at the source code:
This method uses the
SHA256 hashing (HMAC) mechanism to ensure data integrity and is almost always faster and more efficient than a database based OTP verification system.
This does not take into account stuffs like: error handling, http framework or routing etc. just to avoid unnecessary noise.
The full sample source code is available From this link