Intro
In this article, we wil look at how to use AWS Serverless services to set up a basic One-Time Password (OTP) system, which may be used as part of two-factor authentication.
Let us list the tools and technologies used to build this application.
- AWS Lambda
- API Gateway
- DynamoDB
- Simple Email Service - SES
- Amplify Web Hosting
- VueJS for frontend
- Deploy with AWS SAM
Architecture
How it works
In this scenario, we will use a login form built with VueJS and hosted with Amplify static web hosting.
- After the user enters their email and password, an API endpoint is contacted to perform the "
Generate OTP" Lambda function, which generates a 6-digit code along with asession id. - "
Generate OTP" Lambda will save the code andsession idinto aDynamoDBtable after they are generated. - The API endpoint will then return simply the
session idas a response. - The table has DynamoDB streams enabled. As a result, once the data is stored, the "Send Email" Lambda function is called.
The "
Send Email" Lambda function will use theSimple Email Service(SES) to send an email containing the created code to the specified email address.Meanwhile, once the
session idis retrieved from the API, a second form is offered to enter the code, which is then emailed to the specified address.When the user enters and submits the code, it will confirm it along with the
session idusing another API gateway endpoint that will proxy to the "Verify OTP" Lambda function.The Lambda function "
Verify OTP" queries theDynamoDBtable with the specifiedsession-idand code and returns success or error results.
Key points/Lessons learned
In this case, I set
DynamoDBTTL to delete the entries after a certain amount of time to avoid rapidly filling the table. When the TTL expires,DynamoDBwill not destroy your record instantly. It is finally erased, however AWS only guarantees that it will be deleted within 48 hours. As a result, while checking the OTP code, it must take into account the same "expiredAt" parameter that was used to set the TTL.To conveniently query the required data, I used sessionId + OTP code as a primary key when designing the
DynamoDBtable. So, when testing the code, I query theDynamoDBtable by primary key with this combination.When you use
DynamoDBstream as a trigger for Lambda, it receives triggers for allDynamoDBevents (for example, insert, delete, and update). So, within the Lambda function, I had to filter out only the INSERT events using the record's "eventName."I used AWS's own
Simple Email Service(SES) to send emails. To send emails to any address, you must first validate your sending email address. This can be accomplished through a support request.To host the application's
frontend, I used Amplify static web hosting. I used Amplify capabilities such as auto deploys when theGithub repositoryis amended and setting up a custom domain name with a few button clicks.I deployed the backend resources using
AWS SAM. At the time of deployment, the expiry period of theOTPand the number of digits in theOTPcode can be set.
How to set up
Prerequisites
- AWS CLI
- AWS SAM CLI
- Set up and verified SES send email address
Backend
1. Clone the repository
git clone https://github.com/pubudusj/simple-otp
2. Run
sam init && sam deploy -g
The stack's backend will be created once you enter your stack details and AWS environment parameters. Take note of the ApiBaseUrl that is returned (copy it).
Frontend
Copy the
.env.exampleinto.envfile. Now add theApiBaseUrlvalue asVUE_APP_API_BASE_URL.You can either manually deploy the application to your
Amplify web hostingenvironment, or authorize your GitHub repository to do so automatically with every git push.The frontend can be executed locally by navigating to the frontend directory and then running the command
run npm server.
To Delete the stack
To delete the backend, run the command
sam delete
Demo
Demo version of this application is available at :
Feedback
Your valuable feedback on this project is mostly welcome! I would like you to play around with this and if you have any questions or general comments, please reach out to me via Personal Blog, LinkedIn, Twitter or Github.
Thank you for taking the time to read this! Your valuable feedback on this project is mostly welcome! I would like you to play around with this and if you have any questions or general comments, please reach out to me on LinkedIn and Medium to so we can talk more about it. 😅

Top comments (0)