[Easy] Complete user Login and Registration using NodeJS, ExpressJs, MySQL and JWT.
Tags: node, beginners, mysql, authentication
Published: 2021-12-10 19:23:07

Couple months back I was also searching for the same thing, But unluckily I couldn't find any good resources from YouTube and from Google, But somehow from visiting 10 different website for 10 different things I finally managed to get idea of Login and Registration System in NodeJS and MySQL. The thing to get noticed is you will find many resources of Login and Registration System using NodeJS and MongoDB, but there are very few for MySQL or I'll say few with no sense. 

## Prerequisites:
You should be knowing basic of JavaScript, HTML, CSS, Bootstrap, NodeJS, Express, MySQL and its fine if you don't know have advance knowledge in this after completely reading this article you will get the complete IDEA.

## Installing Dependencies: 
Install NodeJS and XAMPP,
NodeJS - [Download NodeJs](https://nodejs.org/en/download/)
XAMPP - [Download XAMPP](https://www.apachefriends.org/download.html)

Run the following command in your root directory terminal: 
`npm install express express-handlebars mysql nodemon bcrypt body-parser cookie-parser dotenv jsonwebtoken`

Look at the folder structure!

![Folder Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0a1z1x34ejziz4dszcob.png)

## Creating Server:
Type the following code in app.js.

-------------------------
```
const express = require('express');
const app = express();
const port = process.env.PORT || 5000;

app.listen(port, () => {
    console.log('Server Started');
});
```

This will create a server on Port 5000. Now you can open http://localhost:5000 on your browser but before that, creating server is not only the thing we have to do so let's import all other dependencies and start writing the code.

## Creating Database and Table:
Create a database and one table, Table should include field like id, name, email, password and bio. Make sure to crange the name of database and table from the code which I have provided.

## Main Code:
In app.js start typing the following code, Check the comments for better understanding.

---------------
```
const express = require('express');
const mysql = require('mysql');
const exphbs = require('express-handlebars');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
require('dotenv').config();

const app = express();
const port = process.env.PORT || 5000;

app.use(bodyParser.urlencoded({
    extended: false
}))

// Converting JSON to JavaScript Objects
app.use(bodyParser.json());

// Accessing Cookies from user's Browser
app.use(cookieParser())

// Telling our backend that the static files of our website are going to be in which folder!!
app.use(express.static('public'));

//Template Engines 
app.engine("hbs", exphbs({ extname: '.hbs' }))
app.set('view engine', 'hbs');

// DataBase Credentials
const pool = mysql.createPool({
    connectionLimit: 100,
    host           : 'localhost',
    user           : 'root',
    password       : '',
    database       : 'users',
})

// Connecting to DB
pool.getConnection((err, connection)=>{
    if(err){
        throw err;
    }
    else{
        console.log('Connection Successful and Connected');
    }
});

// All Routers Middleware Setup => 
const homeRoutes = require('./server/routes/homeRoutes');
app.use('/', homeRoutes);

const authRoutes = require('./server/routes/authRoutes');
app.use('/auth', authRoutes);

app.listen(port, () => {
    console.log('Server Started');
});
```

> NOTE : make sure to hide your database credentials in .env file.

## Creating Routes:

```
//type this following code in authRoute.js

const router = require('express').Router();
const { tokenValidation } = require('../../auth/userToken');
const controllers = require('../controllers/authController');

// Routes
// Login
router.get('/login', controllers.ViewLoginPage)
router.post('/login', controllers.Loginuser)

// Register
router.get('/register', controllers.ViewRegisterPage)
router.post('/register', controllers.RegisterNewPage)

module.exports = router;
```

-----------
```
const router = require('express').Router();
const controllers = require('../controllers/homeController');
const { tokenValidation } = require('../../auth/userToken');

// Routes
router.get('/', controllers.HomePage);
router.get('/user-profile', tokenValidation, controllers.userProfilePage);

//NOTE: dont get confuse with why am i passing to middlewares in route user-profile, once we learn the JWT then you will get this.

module.exports = router;
```

## Creating Controllers for Home and Auth:

```
//type the following code in authControllers.js


const mysql = require('mysql');
const { hashSync, genSaltSync, compareSync } = require('bcrypt');
const { sign } = require('jsonwebtoken');
require('dotenv').config();

const pool = mysql.createPool({
    connectionLimit: 100,
    host: "localhost",
    user: "root",
    password: "",
    database: "users",
})


exports.ViewLoginPage = (req, res) => {
    res.render('login', { title: 'Login' })
}
exports.ViewRegisterPage = (req, res) => {
    res.render('register', { title: 'Register' })
}


//Registration of user
exports.RegisterNewPage = (req, res) => {
    const {name, email, password, bio} = req.body;
    
    //Generating salt for Hashing
    const salt = genSaltSync(10);
    
    //Hashing the password
    const hashPassword = hashSync(password, salt);
    
    
    // Connecting to DB
    pool.getConnection((err, connection) => {
        if (err) {
            throw err;
        }
        else {
            connection.query('select email from users where email = ?', [email], (err, data) => {
                console.log(data)
                if (data.length != 0) {
                    res.render('register', {message: 'Already Registered'})

                }
                else{
                    connection.query('INSERT INTO users SET name = ?, email = ?, bio = ?, password = ?', [name, email, bio, hashPassword], (err, newRegisteredUser) => {
                        if(err){
                            res.render('register', {message: 'Something went wrong, Please try again'})
                        }
                        res.redirect('/auth/login/')
                    })
                }
            })

            
        }
    });
}

//Login the user
exports.Loginuser = (req,res) => {
    const {email, password} = req.body;
    pool.getConnection((err, connection) => {
        if (err) {
            throw err;
        }
        else {
            connection.query('SELECT * FROM users WHERE email = ?', [email], (err,data) => {
                if(err){
                    res.render('login', {message: 'Email or Password is Incorrect'});
                }
                if(data.length == 0){
                    res.render('login', {message: `Email Doesn't exist, Try to register`})
                }
                else{
                    const checkPassword = compareSync(password, data[0].password);
                    if(checkPassword){
                    
                    //Creating the token for logged in user
                        const userToken = sign({result: data[0].email}, process.env.SECRET_KEY, {
                            expiresIn: '600s'
                        })
                        
                        //Sending the token to user's cookie
                        res.cookie('userToken', userToken, {
                            expires: new Date(Date.now() + 600000),
                            httpOnly: true
                        })
                        console.log(userToken)
                        res.redirect('/')
                    };
                    else{
                        res.render('login', {message: 'Email or Password is Incorrect'})
                    };
                };
            });
        };
    });
};
```

--------

```
type the following code in homeControllers.js

const cookieParser = require('cookie-parser');
const { verify } = require('jsonwebtoken');
const mysql = require('mysql');
require('dotenv').config();

const pool = mysql.createPool({
    connectionLimit: 100,
    host: "localhost",
    user: "root",
    password: "",
    database: "users",
})

exports.HomePage = (req, res) => {
    const userToken = req.cookies.userToken;
    if (userToken) {
        verify(userToken, process.env.SECRET_KEY, (err, decoded) => {
            if (err) {
                res.render('home',{ notUser: true })
            }
            else {
                let userEmail = decoded.result;
                pool.getConnection((err, connection) => {
                    if (err) {
                        throw err;
                    }
                    else {
                        connection.query('SELECT * FROM users WHERE email = ?', [userEmail], (err,data) => {
                            res.render('home', {data})
                        })  
                    }
                });
                
            }
        })
    }
    else {
        res.render('home',{notUser: true})
    }
}


exports.userProfilePage = (req, res) => {
    const userToken = req.cookies.userToken;
    if (userToken) {
        verify(userToken, process.env.SECRET_KEY, (err, decoded) => {
            if (err) {
                res.redirect('/auth/login/')
            }
            else {
                let userEmail = decoded.result;
                pool.getConnection((err, connection) => {
                    if (err) {
                        throw err;
                    }
                    else {
                        connection.query('SELECT * FROM users WHERE email = ?', [userEmail], (err,data) => {
                            res.render('userProfile', {data})
                        })  
                    }
                });
                
            }
        })
    }
    else {
        res.redirect('/auth/login/')
    }
}
```

## Checking whether the user is Login Or Not:

```
type this code in userToken.js

const { verify } = require('jsonwebtoken');
require('dotenv').config()

exports.tokenValidation = (req,res,next) => {

	//geeting the stored cookie from user
    const userToken = req.cookies.userToken;
    if(userToken){
    
		//verifiying the stored cookie from user
        verify(userToken, process.env.SECRET_KEY, (err, decoded) => {
            if(err){
                res.redirect('/auth/login/')
            }
            else{
            	// next will help to jump on next controller
                next()
            }
        })
    }
    else{
        res.redirect('/auth/login/')
    }
}
```

## Let's work with frontend:
Here I'm not providing the frontend code because that's simple HTML and CSS, you can create your own designing or still if you want my code then you can take it from my GitHub. User Login and Registration in NodeJS MySQL and JWT

## Middleware explanation:
In the code I haven't explain, why we are using two middlewares in homeRoute.js, that's because first middleware is "validateToken", so when ever user request the route than before going to actual route the user will enter in validateToken and this will check whether the user is login or not if he is login then it will get access of 2nd middleware and if not then user will redirected to login page and user has to login, That's how we protected that route.

## Still Having Doubt?
If you still have any doubt you can message me on Instagram or On LinkedIn:
Instagram:  [@rahulnikam.uiux](https://instagram.com/rahulnikam.uiux)

LinkedIn: [Rahul Nikam (Recommended)](https://www.linkedin.com/in/rahul-nikam-5099b220a/)

## More by me
[watch how to work with OAuth 2.0 Authentication using NodeJS, MySQL, JWT + ReactJS](https://dev.to/rahulnikam/premiumoauth-20-google-using-nodejs-mysql-jwt-reactjs-4kgd)