Introduction: Building a Secure Authentication Service

Introduction: Building a Secure Authentication Service

Introduction

This is the beginning of a 5 article series where I will take you through a detailed guide on how to build a beginner-friendly but solid Authentication service.

If you are stuck in tutorial hell or want to build something to test/ improve your backend skills, this might be the perfect series for you. If you are an experienced backend developer this might not be the correct article for you.

So without wasting any time, let's get started.

Features

Our Auth Service will have a lot of features. It will have 6 endpoints

  1. Register via Email Password

  2. Register via Mobile Number & OTP

  3. Send OTP

  4. Verify OTP

  5. Get Profile

  6. Validate JWT Token

I will do a separate article for all 6 endpoints.

Tech-Stack

We will be using node js as our framework, MongoDB and Redis for database & caching, and Twilio for OTP sending services.

I have also created a fully functional UI in SwiftUI for the same but that is not our concern for now. That will be a completely different article series.

Project Structure

Aim to be as organized as possible from the start. It will help you in the future when the number of files increases. For our current project, I have created 6 main folders.

1) Models

2) Controllers

3) Routes

4) Helpers

5) Middlewares

6) Constants

Apart from these 6, we have our .env file, app.js and server.js which will be present in the root directory.

For today's article, we will have a look at how to set up the .env, app.js, & server.js files.

Setup

.env file is used to store all the secret keys and config. We do not push this file to GitHub by keeping it in .gitignore file.

Here is an example of a .env file for our project

PORT = 3000
TOKEN_KEY = dummytokenkey
TWILIO_ACCOUNT_SID = dummyaccountkey
TWILIO_AUTH_TOKEN = dummyauthtoken
MONGO_URI = dummymongouri

Before moving onto app and server.js we will add dependencies to our project. We will need these external packages/libraries as this will make our lives easier. We will use 8 packages namely express, mongoose, Twilio, redis, bcrypt, JSON web token, express-rate-limit, and dotenv.

I will explain the use of all these packages when the time comes. For now, just do

yarn add express mongoose twilio redis bcrypt jsonwebtoken express-rate-limit dotenv

App.JS & Server.JS

app.js

Our app.js file will include details of middleware and other important declarations related to our app.

First of all, we will import express and create an instance of the express class.

Here is a short definition of express: Express is a node js web application framework that provides broad features for building web and mobile applications. It is used to build a single page, multipage, and hybrid web application. It's a layer built on the top of the Node js that helps manage servers and routes.

After that, we will add two middlewares to our app.

  1. express.json(): The express.json() function is a built-in middleware function in Express. It parses incoming requests with JSON payloads and is based on a body parser.

  2. express.urlencoded() : Just like express.json() converts request body to JSON, it also carries out some other functionalities like converting form-data to JSON etc.

For more detailed info on these 2 middlewares, you can read this stackoverflow post

We will then export our app so that other files can use it whenever needed.

const express = require('express');

const app = express()

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

module.exports = app

server.js

First of all, we will import all the required files. We will need the app we created just now, we will also need our dbservices and redis service which we have just exported from their respective files.

We will try to connect to our db and then we will try to connect to our Redis server. If both are a success, we will tell our app to listen to a port on our local host.

connectDB() & connectRedis() functions are written by us. We will cover it in future articles. For now, you can just ignore that code and create only server.js and import our app in it.

const app = require('./app')
const dbServices = require('./helpers/db')
const redisService = require('./helpers/redis')

dbServices.connectDB().then(()=>{
        redisService.connectRedis().then(()=>{
            app.listen(PORT, () => {
                console.log(`Service running on ${PORT}`)
            })
        }).catch((e) => {
            console.log("Redis error occured ")
        })

}).catch((e)=>{
    console.log("Mongoose Error Occured")
})

Conclusion

So that's it for today's article. To give a quick recap, here is what we did today

  1. Learned how to break our project into various folders

  2. Created a .env file to store our secrets in it.

  3. Installed all the required dependencies using yarn

  4. Created an app file, and registered two important middlewares for our service.

In the next article, we will connect our Mongoose and Redis databases, and write our first endpoint.

I hope that you learned something new today. You can appreciate and support my blogs via.

https://cdn.hashnode.com/res/hashnode/image/upload/v1646372265341/O0KkM6E-0.png

Also, let's connect on Twitter. Follow CSwithIyush for more amazing tutorials, tips/tricks on Flutter & DSA.

Did you find this article valuable?

Support Ayush Pawar by becoming a sponsor. Any amount is appreciated!