Node js Login and Registration REST API with MySQL DB

In this tutorial, you will learn how to create Node js Login and Registration RESTful API using MySQL DB.

The purpose of this tutorial is to give an idea to create this type of authentication based API application using Node JS.


Steps of creating the Node JS Login and Registration REST API

  1. Create database and tables
  2. Setup node js environment and package installation
  3. Creating files
  4. Testing the API

1. Create Database and Tables

For storing the dummy users’ data we will use the MySQL DB, but you can also use the MariaDB.

Database information

  • DB Namenode_auth_api
  • Table Nameusers

So first, create a database called node_auth_api into your MySQL DB. And after that, use the following SQL code to create the users table and the structure of the table.

CREATE TABLE users (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
  email varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
  password varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY email (email)
 ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
users table structure
users table structure

2. Setup node js environment and package installation

Now create a new folder on your desktop called node-login-rest-api, and initialize the npm on this folder.

After initializing the npm, install the following packages –

npm i express express-validator mysql2 jsonwebtoken bcryptjs

After installing the above node packages, my package.json file look like the following –

{
  "name": "node-login-rest-api",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "chandan tudu",
  "license": "ISC",
  "dependencies": {
    "bcryptjs": "^2.4.3",
    "express": "^4.17.1",
    "express-validator": "^6.9.2",
    "jsonwebtoken": "^8.5.1",
    "mysql2": "^2.2.5"
  }
}

3. Creating files for the node js auth based API application

If you are curious to know, that what folders and files and we have to write to make this API application, then see the following image –

Node js login rest api folder structure

First, we will create dbConnection.js at the root of the app folder to make the database connection.

const mysql = require("mysql2");

const db_connection = mysql
  .createConnection({
    host: "localhost", // HOST NAME
    user: "root", // USER NAME
    database: "node_auth_api", // DATABASE NAME
    password: "", // DATABASE PASSWORD
  })
  .on("error", (err) => {
    console.log("Failed to connect to Database - ", err);
  });

module.exports = db_connection;

After making the DB Connection, Now we will set up our routes, and for that, we have to create the routes.js at the root of the app folder.

const router = require('express').Router();
const {body} = require('express-validator');
const {register} = require('./controllers/registerController');
const {login} = require('./controllers/loginController');
const {getUser} = require('./controllers/getUserController');

router.post('/register', [
    body('name',"The name must be of minimum 3 characters length")
    .notEmpty()
    .escape()
    .trim()
    .isLength({ min: 3 }),
    body('email',"Invalid email address")
    .notEmpty()
    .escape()
    .trim().isEmail(),
    body('password',"The Password must be of minimum 4 characters length").notEmpty().trim().isLength({ min: 4 }),
], register);


router.post('/login',[
    body('email',"Invalid email address")
    .notEmpty()
    .escape()
    .trim().isEmail(),
    body('password',"The Password must be of minimum 4 characters length").notEmpty().trim().isLength({ min: 4 }),
],login);

router.get('/getuser',getUser);

module.exports = router;

Now we will create the route.js controllers. So first, create a new folder called controllers at the root of the app folder.

Inside controllers folder we have to create three controllers –

  1. registerController.js – for inserting new user.
  2. loginController.js – for the login user.
  3. getUserController.js – for fetching the user details using the JWT token.
const {validationResult} = require('express-validator');
const bcrypt = require('bcryptjs');
const conn = require('../dbConnection').promise();

exports.register = async(req,res,next) => {
    const errors = validationResult(req);

    if(!errors.isEmpty()){
        return res.status(422).json({ errors: errors.array() });
    }

    try{

        const [row] = await conn.execute(
            "SELECT `email` FROM `users` WHERE `email`=?",
            [req.body.email]
          );

        if (row.length > 0) {
            return res.status(201).json({
                message: "The E-mail already in use",
            });
        }

        const hashPass = await bcrypt.hash(req.body.password, 12);

        const [rows] = await conn.execute('INSERT INTO `users`(`name`,`email`,`password`) VALUES(?,?,?)',[
            req.body.name,
            req.body.email,
            hashPass
        ]);

        if (rows.affectedRows === 1) {
            return res.status(201).json({
                message: "The user has been successfully inserted.",
            });
        }
        
    }catch(err){
        next(err);
    }
}
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const {validationResult} = require('express-validator');
const conn = require('../dbConnection').promise();


exports.login = async (req,res,next) =>{
    const errors = validationResult(req);

    if(!errors.isEmpty()){
        return res.status(422).json({ errors: errors.array() });
    }

    try{

        const [row] = await conn.execute(
            "SELECT * FROM `users` WHERE `email`=?",
            [req.body.email]
          );

        if (row.length === 0) {
            return res.status(422).json({
                message: "Invalid email address",
            });
        }

        const passMatch = await bcrypt.compare(req.body.password, row[0].password);
        if(!passMatch){
            return res.status(422).json({
                message: "Incorrect password",
            });
        }

        const theToken = jwt.sign({id:row[0].id},'the-super-strong-secrect',{ expiresIn: '1h' });

        return res.json({
            token:theToken
        });

    }
    catch(err){
        next(err);
    }
}
const jwt = require('jsonwebtoken');
const conn = require('../dbConnection').promise();

exports.getUser = async (req,res,next) => {

    try{

        if(
            !req.headers.authorization ||
            !req.headers.authorization.startsWith('Bearer') ||
            !req.headers.authorization.split(' ')[1]
        ){
            return res.status(422).json({
                message: "Please provide the token",
            });
        }

        const theToken = req.headers.authorization.split(' ')[1];
        const decoded = jwt.verify(theToken, 'the-super-strong-secrect');

        const [row] = await conn.execute(
            "SELECT `id`,`name`,`email` FROM `users` WHERE `id`=?",
            [decoded.id]
        );

        if(row.length > 0){
            return res.json({
                user:row[0]
            });
        }

        res.json({
            message:"No user found"
        });
        
    }
    catch(err){
        next(err);
    }
}

At the end of creating the files, we will create our main JS file index.js.

const express = require('express');
const routes = require('./routes');
const app = express();

app.use(express.json());
app.use(routes);
// Handling Errors
app.use((err, req, res, next) => {
    // console.log(err);
    err.statusCode = err.statusCode || 500;
    err.message = err.message || "Internal Server Error";
    res.status(err.statusCode).json({
      message: err.message,
    });
});

app.listen(3000,() => console.log('Server is running on port 3000'));

4. Time to test the API

So first, start the node application and MySQL Server. And to test the API I’ll use the Postman software.

POST - http://localhost:3000/register
Register a user through api on postman

POST - http://localhost:3000/login

Copy the received token

Login user through api

GET - http://localhost:3000/getuser

Use the copied token to get the user details.

Send the token through the header.

  • header key – Authorization
  • Authorization Value – Bearer the_token
send the jwt token through the header

Now send the request –

Fetching loged in user

And this is end, hope you enjoy it.

Checkout this related tutorial – CRUD RESTful API using Node.js

Leave a Reply