How to Forget or Reset Password in Node js Express and MySQL?

21-Dec-2022

.

Admin

How to Forget or Reset Password in Node js Express and MySQL?

Hello Friends,

In this article we will cover how to implement how to forget or reset passwords in node js express and MySQL. I want to share with you that add forgot/reset password to the login-authentication system in MySQL. This example will help you create secure password flows with nodejs and MySQL. Here you will learn implement a secure password reset in node js.

Unfortunately, the reset password workflow gets short shrift and limited attention during application development. This not only can lead to a frustrating user experience but can also leave your application with gaping security holes.

Step 1: Install Node Express App JS


Execute the following command on the terminal to install the express js app:

express --view=ejs blog

Then open blog setup with any text editor. And use the following command to enter your blog app directories, So open your cmd and run the following command:

cd blog

Your node js express js + mysql reset password email app structure looks like this:

Step 2: Install Required Node js Modules

Install some required node js modules, so open again your cmd and run the following commands:

npm install express-flash --save

npm install express-session --save

npm install method-override --save

npm install mysql --save

npm install rand-token --save

npm install body-parser --save

npm install bcrypt

npm install

Express-flash – Flash is an extension of connect-flash with the ability to define a flash message and render it without redirecting the request.

Express-session – Express-session is used to make a session as like in PHP. In this node js MySQL crud tutorial, the session is needed as the express requirement of express-flash.

Method-override – NPM is used to run a DELETE and PUT method from an HTML form. Several web browsers only support GET and POST methods.

MySQL – Driver to connect node.js with MySQL.

rand-token – Generate random tokens from your choice of randomness.

body-parser – Body-parser is the Node. js body parsing middleware. It is responsible for parsing the incoming request bodies in a middleware before you handle it.

Nodemailer – Nodemailer is a module for Node.js applications to allow easy as cake email sending. The project got started back in 2010 when there was no sane option to send email messages, today it is the solution most Node. js users turn to by default.

bcrypt – Bcrypt is a popular and trusted method for salt and hashing passwords. You have learned to use bcrypt’s NodeJS library to salt and hash a password before storing it in a database. You have also learned how to use the bcrypt compare function to compare a password to a hash, which is necessary for authentication.

If you want to send mail from localhost or without SSL certificate, you can execute the following command on your terminal also:

npm config set strict-ssl false --global

set NODE_TLS_REJECT_UNAUTHORIZED=0

Step 3: Connect Node Express JS App with DB

Before connecting DB to your node js email verification application, create a table in your database by using the following SQL query:

-- phpMyAdmin SQL Dump

-- version 5.0.2

-- https://www.phpmyadmin.net/

--

-- Host: 127.0.0.1

-- Generation Time: Sep 11, 2021 at 02:49 PM

-- Server version: 10.4.14-MariaDB

-- PHP Version: 7.4.9

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";

START TRANSACTION;

SET time_zone = "+00:00";

--

-- Database: `my-node`

--

-- --------------------------------------------------------

--

-- Table structure for table `users`

--

CREATE TABLE `users` (

`id` int(11) NOT NULL,

`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,

`token` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL

)

ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

--

-- Indexes for dumped tables

--

--

-- Indexes for table `users`

--

ALTER TABLE `users`

ADD PRIMARY KEY (`id`),

ADD UNIQUE KEY `email` (`email`);

--

-- AUTO_INCREMENT for dumped tables

--

--

-- AUTO_INCREMENT for table `users`

--

ALTER TABLE `users`

MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

COMMIT;

Then visit your app root directory and create one file name database.js. Then add the following code into your database.js file:

var mysql=require('mysql');

var connection=mysql.createConnection({

host:'localhost',

user:'root',

password:'',

database:'my-node'

});

connection.connect(function(error){

if(!!error){

console.log(error);

}else{

console.log('Connected!:)');

}

});

module.exports = connection;

Note that This file is used to connect your node express js app to MySQL DB.

Step 4: Import Installed Modules in app.js

Import the above installed node js modules in the app.js file; So, Open your app.js file and import all the packages above installed in app.js file.

So go to app.js file and update the following code:

var createError = require('http-errors');

var express = require('express');

var path = require('path');

var cookieParser = require('cookie-parser');

var logger = require('morgan');

var flash = require('express-flash');

var session = require('express-session');

var bodyParser = require('body-parser');

var indexRouter = require('./routes/index');

var usersRouter = require('./routes/users');

var app = express();

// view engine setup

app.set('views', path.join(__dirname, 'views'));

app.set('view engine', 'ejs');

app.use(logger('dev'));

app.use(express.json());

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

app.use(cookieParser());

app.use(express.static(path.join(__dirname, 'public')));

app.use(session({

secret: '123458cat',

resave: false,

saveUninitialized: true,

cookie: { maxAge: 60000 }

}))

app.use(flash());

//app.use('/', indexRouter);

app.use('/', usersRouter);

// catch 404 and forward to error handler

app.use(function(req, res, next) {

next(createError(404));

});

// error handler

app.use(function(err, req, res, next) {

// set locals, only providing error in development

res.locals.message = err.message;

res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page

res.status(err.status || 500);

res.render('error');

});

app.listen(4000, function () {

console.log('Node app is running on port 4000');

});

module.exports = app;

Step 5: Create Forget and Reset Password Route

Create forget and reset password routes with send link email; so visit routes directory and open index.js route file and create routes as shown below:

Create Email Send Function with Gmail nodemailer configuration

//send email

function sendEmail(email, token) {

var email = email;

var token = token;

var mail = nodemailer.createTransport({

service: 'gmail',

auth: {

user: '', // Your email id

pass: '' // Your password

}

});

var mailOptions = {

from: 'nicesnippets@gmail.com',

to: email,

subject: 'Reset Password Link - nicesnippets.com',

html: '

You requested for reset password, kindly use this link to reset your password

'

};

mail.sendMail(mailOptions, function(error, info) {

if (error) {

console.log(1)

} else {

console.log(0)

}

});

}

Now open the link https://myaccount.google.com/lesssecureapps to Allow less secure apps: ON. It will send the email using Gmail account.

Create Reset Password Link with Send to Email

/* send reset password link in email */

router.post('/reset-password-email', function(req, res, next) {

var email = req.body.email;

//console.log(sendEmail(email, fullUrl));

connection.query('SELECT * FROM users WHERE email ="' + email + '"', function(err, result) {

if (err) throw err;

var type = ''

var msg = ''

console.log(result[0]);

if (result[0].email.length > 0) {

var token = randtoken.generate(20);

var sent = sendEmail(email, token);

if (sent != '0') {

var data = {

token: token

}

connection.query('UPDATE users SET ? WHERE email ="' + email + '"', data, function(err, result) {

if(err) throw err

})

type = 'success';

msg = 'The reset password link has been sent to your email address';

} else {

type = 'error';

msg = 'Something goes to wrong. Please try again';

}

} else {

console.log('2');

type = 'error';

msg = 'The Email is not registered with us';

}

req.flash(type, msg);

res.redirect('/');

});

})

Create Reset/Update Password route

/* update password to database */

router.post('/update-password', function(req, res, next) {

var token = req.body.token;

var password = req.body.password;

connection.query('SELECT * FROM users WHERE token ="' + token + '"', function(err, result) {

if (err) throw err;

var type

var msg

if (result.length > 0) {

var saltRounds = 10;

// var hash = bcrypt.hash(password, saltRounds);

bcrypt.genSalt(saltRounds, function(err, salt) {

bcrypt.hash(password, salt, function(err, hash) {

var data = {

password: hash

}

connection.query('UPDATE users SET ? WHERE email ="' + result[0].email + '"', data, function(err, result) {

if(err) throw err

});

});

});

type = 'success';

msg = 'Your password has been updated successfully';

} else {

console.log('2');

type = 'success';

msg = 'Invalid link; please try again';

}

req.flash(type, msg);

res.redirect('/');

});

})

Complete source code of users.js route:

var express = require('express');

var router = express.Router();

var connection = require('../database.js');

var nodemailer = require('nodemailer');

var bcrypt = require('bcrypt');

var randtoken = require('rand-token');

//send email

function sendEmail(email, token) {

var email = email;

var token = token;

var mail = nodemailer.createTransport({

service: 'gmail',

auth: {

user: '', // Your email id

pass: '' // Your password

}

});

var mailOptions = {

from: 'nicesnippets@gmail.com',

to: email,

subject: 'Reset Password Link - Nicesnippets.com',

html: '

You requested for reset password, kindly use this link to reset your password

'

};

mail.sendMail(mailOptions, function(error, info) {

if (error) {

console.log(1)

} else {

console.log(0)

}

});

}

/* home page */

router.get('/', function(req, res, next) {

res.render('index', {

title: 'Forget Password Page'

});

});

/* send reset password link in email */

router.post('/reset-password-email', function(req, res, next) {

var email = req.body.email;

//console.log(sendEmail(email, fullUrl));

connection.query('SELECT * FROM users WHERE email ="' + email + '"', function(err, result) {

if (err) throw err;

var type = ''

var msg = ''

console.log(result[0]);

if (result[0].email.length > 0) {

var token = randtoken.generate(20);

var sent = sendEmail(email, token);

if (sent != '0') {

var data = {

token: token

}

connection.query('UPDATE users SET ? WHERE email ="' + email + '"', data, function(err, result) {

if(err) throw err

})

type = 'success';

msg = 'The reset password link has been sent to your email address';

} else {

type = 'error';

msg = 'Something goes to wrong. Please try again';

}

} else {

console.log('2');

type = 'error';

msg = 'The Email is not registered with us';

}

req.flash(type, msg);

res.redirect('/');

});

})

/* reset page */

router.get('/reset-password', function(req, res, next) {

res.render('reset-password', {

title: 'Reset Password Page',

token: req.query.token

});

});

/* update password to database */

router.post('/update-password', function(req, res, next) {

var token = req.body.token;

var password = req.body.password;

connection.query('SELECT * FROM users WHERE token ="' + token + '"', function(err, result) {

if (err) throw err;

var type

var msg

if (result.length > 0) {

var saltRounds = 10;

// var hash = bcrypt.hash(password, saltRounds);

bcrypt.genSalt(saltRounds, function(err, salt) {

bcrypt.hash(password, salt, function(err, hash) {

var data = {

password: hash

}

connection.query('UPDATE users SET ? WHERE email ="' + result[0].email + '"', data, function(err, result) {

if(err) throw err

});

});

});

type = 'success';

msg = 'Your password has been updated successfully';

} else {

console.log('2');

type = 'success';

msg = 'Invalid link; please try again';

}

req.flash(type, msg);

res.redirect('/');

});

})

module.exports = router;

Step 6: Create views

Create forget password and reset/update password pages; so visit your app root directory and find the views directory.

Forget Password Page

Then inside this directory create one file index.ejs. And add the following code into it:

<!DOCTYPE html>

<html>

<head>

<title>How to Forget or Reset Password in Node js Express and MySQL? - Nicesnippets.com</title>

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">

</head>

<body class="container mt-3">

<% if (messages.error) { %>

<p style="color:red"><%- messages.error %></p>

<% } %>

<% if (messages.success) { %>

<p style="color:green"><%- messages.success %></p>

<% } %>

<h1 class="mb-3"><%= title %></h1>

<form action="/reset-password-email" method="post" name="form1">

<div class="form-group">

<label for="exampleInputEmail1">Email</label>

<input type="email" name="email" class="form-control" id="email" aria-describedby="emailHelp" placeholder="Enter email" value="">

</div>

<input type="submit" class="btn btn-primary" value="Send Verification Link">

</form>

</body>

</html>

Reset/Update Password Page

Then inside this directory create one file reset-password.ejs. And add the following code into it:

<!DOCTYPE html>

<html>

<head>

<title>How to Forget or Reset Password in Node js Express and MySQL? - nicesnippets.com</title>

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">

</head>

<body class="container mt-3">

<% if (messages.error) { %>

<p style="color:red"><%- messages.error %></p>

<% } %>

<% if (messages.success) { %>

<p style="color:green"><%- messages.success %></p>

<% } %>

<h1 class="mb-3">How to Forget or Reset Password in Node js Express and MySQL?</h1>

<form action="/update-password" method="post" name="form1">

<input type="hidden" name="token" class="form-control" value="<%= token %>">

<div class="form-group">

<label for="exampleInputEmail1">Password</label>

<input type="password" name="password" class="form-control" id="password" aria-describedby="emailHelp" placeholder="Please Enter New Password" value="">

</div>

<input type="submit" class="btn btn-primary" value="Update Password">

</form>

</body>

</html>

Step 7: Run Development Server

You can use the following command to run the development server:

//run the below command

npm start

After running this command open your browser and hit

http://127.0.0.1:4000/

If you found any error while sending an email with Gmail SMTP; So you can follow these two steps and resolve it:

  • You have to enable the Gmail service to use it in third-party apps. In case you miss doing so, we may face a such an error. To resolve this error just login in Gmail account and enable less secure apps using this link https://myaccount.google.com/lesssecureapps
  • I hope it can help you...

    #Node.js Express

    #Node JS