REST API or backend server development for a web app or mobile app is becoming more popular day by day. In this tutorial I will show how to create a REST API backend server with Node & Express framework with MongoDB database. I will also show you how to secure your APIs with secured token based authentication system like JWT.

Excited?

Let’s start!

What is Node.js ?

Node.js is an open-source, cross-platform, back-end JavaScript runtime environment that runs on the V8 engine and executes JavaScript code outside a web browser.

What is Express.js?

Express.js, or simply Express, is a back end web application framework for Node.js, released as free and open-source software under the MIT License. It is designed for building web applications and APIs. It has been called the de facto standard server framework for Node.js.

What is MongoDB?

MongoDB is a source-available cross-platform document-oriented database program. Classified as a NoSQL database program, MongoDB uses JSON-like documents with optional schemas. MongoDB is developed by MongoDB Inc. and licensed under the Server Side Public License.

What is JWT authentication?

JSON Web Token is a proposed Internet standard for creating data with optional signature and/or optional encryption whose payload holds JSON that asserts some number of claims. The tokens are signed either using a private secret or a public/private key.

This tutorial at a glance:

  • Environment setup
  • MongoDB setup & connection
  • Authentication

Environment setup:

I will use Ubuntu 20.04 as my development server. You can use Windows & Mac also.

We have to install node first. Open Terminal and type:

sudo apt update
sudo apt install nodejs
nodejs -v

If you successfully installed node in your machine, you will see node version number in the Terminal console.

Now, we have to install npm

sudo apt install npm
npm -v

If you see npm version in your Terminal console, then you successfully installed npm in your machine.

For Windows & Mac user, follow this link to download node. node and npm will download together in Windows & Mac.

Now, we have to install an IDE for coding. For this tutorial, I will use Visual Studio Code because its free and very easy to use. To download Visual Studio Code on your machine, run this command:

sudo snap install --classic code

Download Visual Studio Code on Windows

Download Visual Studio Code on Mac

Now create a folder named tutorial. We will keep everything is this folder. I have created this tutorial folder in my Desktop.

Note : tutorial folder may need special permission to read and write files inside it. For this reason, Open Terminal > Go to your folder > Run the command below:

sudo chmod -R 777 ./

or

// if you want to allow permission from Desktop
sudo chmod -R 777 tutorial

Start Visual Studio Code and open your tutorial folder. This will look like below.

Now click Terminal option in Visual Studio Code and open a new terminal windows . It is equivalent to your Ubuntu’s default Terminal.

In new terminal windows, run the command below to start a new node project.

npm init

Note : It will ask you to enter project properties, don’t input anything, just press Enter, Enter, Enter until project is created.

You will see a new file named package.json is created in your tutorial folder.

Replace the code inside package.json file with the code below :

{
  "name": "tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon app.js"
  },
  "author": "",
  "license": "ISC"
}


Now, we need to install Express framework.

Run the command below in your Visual Studio Code terminal:

npm install express

Install nodemon

npm install nodemon

Create a new file in tutorial folder named app.js and replace with the code below:

const express = require('express');
const app = express();

app.get('/',(req,res) =>{

    res.send("Your backend server based on Node and Express is ready to role!");

});

app.listen(3000);

Now got to terminal and just run this command:

npm start

You server will started! Open a browser, paste and hit this link :

localhost:3000

If you see something like this in your browser then Congratulation! Your REST API server is ready. You are all set to go to next steps.

If you want to access your server from any device within your network (same WiFi or LAN), just run this command with your machine IP address.

npm start your_machine_ip:3000

In my case, my machine IP is: 192.168.31.117

So my command will be:

npm start 192.168.31.117:3000

Note : I use this command to test my REST APIs if my team develop mobile apps (Android or iOS) because my mobile app developers and I are connected to the same WiFi network.


MongoDB setup:

Its time to connect our server with database to create a real-life project. For this, you have to install MongoDB in your machine first. To install MongoDB in your machine, run this command below (You can use Ubuntu’s default Terminal or Visual Studio Code’s Terminal):

sudo apt install mongodb

To check if MongoDB installed or not on your system, run the command below:

mongod --version

If it shows version number then you have installed MongoDB successfully on your machine.

Now type the command:

mongo

It will enter Mongo Shell editor, you can edit,modify databases,collections etc. here manually.

Don’t worry, we are here just to create our database! First check your current databases by this command below.

show dbs

You will see something like this.

admin 0.000GB

config 0.000GB

local 0.000GB

These are the local databases for settings purpose. We have to create our own database to use with our Node Express server.

Just write this command on your Terminal.

use tutorial

Your database will be created successfully. But you can’t view it by show dbs command because we did not input any data into our new database and MongoDB won’t show empty database.

Our job is done here. Press Control + C at the same time to exit from MongoDB shell window.

Go to Visual studio code and create a new folder named db. Then create a new file named database.js inside db folder > paste the code below into that file.

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/tutorial', {useNewUrlParser: true, useUnifiedTopology: true});

var conn = mongoose.connection;

conn.on('connected', function() {
    console.log('database is connected successfully');
});
conn.on('disconnected',function(){
    console.log('database is disconnected successfully');
})

conn.on('error', console.error.bind(console, 'connection error:'));

module.exports = conn;

Add this line in your app.js file.

var dbConn = require('./db/database');

Your app.js will be:

const express = require('express');
const app = express();

var dbConn = require('./db/database');

app.get('/',(req,res) =>{


    res.send("Your backend server based on Node and Express is ready to role!");

});


app.listen(3000);

You have to install mongoose to connect MongoDB database and Node Express server. Run this command in terminal.

npm install mongoose

Now start the server again.

npm start

//or 
npm start 192.168.31.117:3000

If you see the message “database is connected successfully” then fine! Your database connected with your Node Express server perfectly.

Now we have to create some APIs

  • createUser (This api will create a new user with various info)
  • loginUser (This api will verify user’s email and password with database in server)
  • showUserInfo (This api will show user’s info when it get called)

Now create new folder named models. Create e new file named userModel.js inside models folder. Paste the code below into userModel.js file.

var mongoose=require('mongoose');
var db = require('../db/database');

// create an schema
var userSchema = new mongoose.Schema({
            email: String,
            password:String,
            name:String,
            age: Number,
            country: String
        });

userTable=mongoose.model('users',userSchema, 'UserData');
        
module.exports = userTable

Replace your app.js code with the code below :

const express = require('express');

const app = express();
app.use(express.json());

var dbConn = require('./db/database');

const userModel = require('./models/userModel');



app.get('/',(req,res) =>{


    res.send("Your backend server based on Node and Express is ready to role!");

});

app.post('/createUser',(req,res) =>{


    
    dbConn.collection("UserData").find({email : req.body.email}).toArray(function(err, result) {
        if (err) throw err;
        
        if(result.length > 0){
            res.json({ code: 301, data : "User already exists with this email"});
        }else{

            var data1 = new userModel(req.body);
            data1.save(function (err, dataHolder) {
                if (err) return console.error(err);
        
                //console.log(dataHolder.full_name + " saved to UserData collection.");
                res.json({ code: 200, data : dataHolder.name + " saved successfully"
                 });
        
              });
        
            
        }
      });

  

});


app.post('/loginUser',(req,res) =>{


    dbConn.collection("UserData").find({email : req.body.email, password : req.body.password}).toArray(function(err, result) {
        if (err) throw err;
        
        if(result.length > 0){

            res.json({ code: 200, data : "Login successful"});
            
        }else{

            res.json({ code: 301, data : "Wrong email or password!"});

            
        }
      });



});

app.get('/showUserInfo',(req,res) =>{


    

      dbConn.collection("UserData").find({email : req.body.email}).toArray(function(err, result) {
        if (err) throw err;
        
        if(result.length > 0){

            res.json({ code: 200, data : result});
            
        }else{

            res.json({ code: 301, data : "Wrong email or password!"});

            
        }
      });

   
    

});


app.listen(3000);


Run the server with npm start.

We need Postman to test our APIs. Download Postman by the command below. For windows and Mac, Postman has desktop installer version.

sudo snap install postman

Open postman and add your APIs like below:

  • Create User API
createUser
  • Login User API
loginUser
  • Show User Info API
showUserInfo

Congratulation! You are successfully using MongoDB with your Node Express REST API server. But these APIs are no secured, we should use some security layer to protect our APIs.

Authentication:

We will use JWT authentication to protect our APIs. Go to terminal and run these commands:

npm install jsonwebtoken
npm install dotenv

In our app.js file, add 2 functions.

function generateAccessToken(data) {
    return jwt.sign({data}, my_secret_key, { expiresIn: '1800s' });
  }

This function will create a JWT access token for 30 minutes. You can increase as your wish.

function authenticateToken(req, res, next){
    const authHeader = req.headers.authorization;

    if (authHeader) {
        const token = authHeader.split(' ')[1];

        jwt.verify(token, my_secret_key, (err, user) => {
            if (err) {
                //return res.sendStatus(403);
                return res.json({ 
                    code: 403, 
                    msg : "Not Allowed"
                });
            }

            //req.user = user;
            if(req.body.email == user.data.email ){

                next();
                

            }else{

                return res.json({ 
                    code: 401, 
                    msg : "Unauthorized"
                });

            }
            
        });
    } else {
        //res.sendStatus(401);
        return res.json({ 
            code: 401, 
            msg : "Unauthorized"
        });
        
    }
};

This function will work as Middle-ware when you call other APIs except login API.

Select app.js file and replace with the code below.

const express = require('express');

var jwt = require('jsonwebtoken');
var dotenv = require('dotenv');

const app = express();
app.use(express.json());



var dbConn = require('./db/database');

const userModel = require('./models/userModel');

var my_secret_key = 'sdfsdffss@#%$@#$SDFSDFSFSDF$#%@!EDFDHBFD*%^5445dfgdfgdt345345345345s9767dfgdg3534#$#$#$.,;sdfsdf345324';



app.get('/',(req,res) =>{


    res.send("Your backend server based on Node and Express is ready to role!");

});

app.post('/createUser',(req,res) =>{


    
    dbConn.collection("UserData").find({email : req.body.email}).toArray(function(err, result) {
        if (err) throw err;
        
        if(result.length > 0){
            res.json({ code: 301, data : "User already exists with this email"});
        }else{

            var data1 = new userModel(req.body);
            data1.save(function (err, dataHolder) {
                if (err) return console.error(err);
        
                //console.log(dataHolder.full_name + " saved to UserData collection.");
                res.json({ code: 200, data : dataHolder.name + " saved successfully"
                 });
        
              });
        
            
        }
      });

  

});


app.post('/loginUser',(req,res) =>{


    dbConn.collection("UserData").find({email : req.body.email, password : req.body.password}).toArray(function(err, result) {
        if (err) throw err;
        
        if(result.length > 0){

            
            const data = {email : req.body.email};
            const accessToken = generateAccessToken(data);

            res.json({ code: 200, access_token : accessToken});
            
        }else{

            res.json({ code: 301, data : "Wrong email or password!"});

            
        }
      });



});

app.post('/showUserInfo',authenticateToken, (req,res) =>{


    

      dbConn.collection("UserData").find({email : req.body.email}).toArray(function(err, result) {
        if (err) throw err;
        
        if(result.length > 0){

            res.json({ code: 200, data : result});
            
        }else{

            res.json({ code: 301, data : "Wrong email or password!"});

            
        }
      });

   
    

});


function generateAccessToken(data) {
    return jwt.sign({data}, my_secret_key, { expiresIn: '1800s' });
  }

function authenticateToken(req, res, next){
    const authHeader = req.headers.authorization;

    if (authHeader) {
        const token = authHeader.split(' ')[1];

        jwt.verify(token, my_secret_key, (err, user) => {
            if (err) {
                //return res.sendStatus(403);
                return res.json({ 
                    code: 403, 
                    msg : "Not Allowed"
                });
            }

            //req.user = user;
            if(req.body.email == user.data.email ){

                next();
                

            }else{

                return res.json({ 
                    code: 401, 
                    msg : "Unauthorized"
                });

            }
            
        });
    } else {
        //res.sendStatus(401);
        return res.json({ 
            code: 401, 
            msg : "Unauthorized"
        });
        
    }
};


app.listen(3000);


Now

  • Our Login User API will look like below. It will generate a nice Access Token to use as security layer while calling other general purpose APIs.
  • In Show User Info API, we have to put this Access Token (Authorization > Bearer Token) with our user email for token validation. If the token is valid, then server will response you with the user detailed info.

Hurrah! You successfully created your REST API server with Node, Express framework and MongoDB database with JWT secured token based authentication. Congratulation buddy!
Now you are ready to develop any type of real-life backend server of your own. Best of luck!

By the way, we should not save and serve password in Plain Text for security reason! We should encrypt it before saving it to database and serving over networks. I will show that very soon.. Stay update!

Download Source Code

Leave a Reply

Your email address will not be published. Required fields are marked *