Building a Secure Password Reset System with Node.js and MySQL

In this guide, we'll walk through implementing a password reset feature using Node.js, Express, MySQL, and bcrypt. This will ensure users can securely reset their passwords through an email token-based system. 1. Setting Up the Node.js Project Start by installing the required dependencies: npm install express mysql bcrypt ejs body-parser express – Framework for handling HTTP requests mysql – To interact with MySQL database bcrypt – For hashing passwords securely ejs – To render views body-parser – To parse form data Next, create an index.js file and set up the server: const express = require('express'); const mysql = require('mysql'); const bcrypt = require('bcrypt'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.urlencoded({ extended: true })); const db = mysql.createConnection({ host: 'localhost', user: 'root', password: '', database: 'mydb' }); db.connect(err => { if (err) throw err; console.log('Connected to MySQL'); }); 2. Validating the Reset Token When a user clicks the "Forgot Password" link, they receive a token via email. The API must verify that token before allowing a password reset. const resetPasswordLoad = (req, res) => { const token = req.query.token; if (!token) return res.render('404'); db.query('SELECT * FROM password_resets WHERE token=? LIMIT 1', [token], (err, result) => { if (err || result.length === 0) return res.render('404'); db.query('SELECT * FROM users WHERE email=? LIMIT 1', [result[0].email], (err, user) => { if (err) return res.render('404'); res.render('reset-password', { user: user[0] }); }); }); }; Retrieves the token from the URL Checks if it exists in the password_resets table If valid, fetches the corresponding user and renders the password reset form 3. Creating the Reset Password Form Create views/reset-password.ejs: New Password: Reset Password 4. Updating the Password in MySQL Handle the password update in index.js: app.post('/reset-password', (req, res) => { const { email, password } = req.body; if (!password) { return res.render('message', { message: 'Password cannot be empty!' }); } const hashedPassword = bcrypt.hashSync(password, 10); db.query('UPDATE users SET password=? WHERE email=?', [hashedPassword, email], (err) => { if (err) return res.render('message', { message: 'Error updating password.' }); db.query('DELETE FROM password_resets WHERE email=?', [email], () => { res.render('message', { message: 'Password reset successful! You can now log in.' }); }); }); }); Hashes the new password before updating it Deletes the password reset token after a successful reset 5. Displaying Success/Error Messages Create views/message.ejs: 6. Running the Server Start the Node.js server: node index.js Now, the password reset system is functional! While working on the password reset system in Node.js and MySQL, I wanted to ensure both security and efficiency. Using verification tokens added a layer of authentication, while hashed passwords protected user data. Additionally, implementing proper validation helped prevent errors and improve reliability. This approach made the system more robust and user-friendly.

Mar 12, 2025 - 03:23
 0
Building a Secure Password Reset System with Node.js and MySQL

In this guide, we'll walk through implementing a password reset feature using Node.js, Express, MySQL, and bcrypt. This will ensure users can securely reset their passwords through an email token-based system.

1. Setting Up the Node.js Project

Start by installing the required dependencies:

npm install express mysql bcrypt ejs body-parser

express – Framework for handling HTTP requests
mysql – To interact with MySQL database
bcrypt – For hashing passwords securely
ejs – To render views
body-parser – To parse form data

Next, create an index.js file and set up the server:

const express = require('express');
const mysql = require('mysql');
const bcrypt = require('bcrypt');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.urlencoded({ extended: true }));

const db = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: '',
    database: 'mydb'
});

db.connect(err => {
    if (err) throw err;
    console.log('Connected to MySQL');
});

2. Validating the Reset Token

When a user clicks the "Forgot Password" link, they receive a token via email. The API must verify that token before allowing a password reset.

const resetPasswordLoad = (req, res) => {
    const token = req.query.token;
    if (!token) return res.render('404');

    db.query('SELECT * FROM password_resets WHERE token=? LIMIT 1', [token], (err, result) => {
        if (err || result.length === 0) return res.render('404');

        db.query('SELECT * FROM users WHERE email=? LIMIT 1', [result[0].email], (err, user) => {
            if (err) return res.render('404');
            res.render('reset-password', { user: user[0] });
        });
    });
};


  • Retrieves the token from the URL
  • Checks if it exists in the password_resets table
  • If valid, fetches the corresponding user and renders the password reset form

3. Creating the Reset Password Form

Create views/reset-password.ejs:

4. Updating the Password in MySQL

Handle the password update in index.js:

app.post('/reset-password', (req, res) => {
    const { email, password } = req.body;

    if (!password) {
        return res.render('message', { message: 'Password cannot be empty!' });
    }

    const hashedPassword = bcrypt.hashSync(password, 10);

    db.query('UPDATE users SET password=? WHERE email=?', [hashedPassword, email], (err) => {
        if (err) return res.render('message', { message: 'Error updating password.' });

        db.query('DELETE FROM password_resets WHERE email=?', [email], () => {
            res.render('message', { message: 'Password reset successful! You can now log in.' });
        });
    });
});

  • Hashes the new password before updating it
  • Deletes the password reset token after a successful reset

5. Displaying Success/Error Messages

Create views/message.ejs:

<% if (message) { %>
    

<%= message %>

<% } %>

6. Running the Server

Start the Node.js server:

node index.js

Now, the password reset system is functional!

While working on the password reset system in Node.js and MySQL, I wanted to ensure both security and efficiency. Using verification tokens added a layer of authentication, while hashed passwords protected user data. Additionally, implementing proper validation helped prevent errors and improve reliability. This approach made the system more robust and user-friendly.