DEV Community

Cover image for Building a Secure Password Reset System with Node.js and MySQL
Shreyansi Shrestha
Shreyansi Shrestha

Posted on

1

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
Enter fullscreen mode Exit fullscreen mode

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');
});
Enter fullscreen mode Exit fullscreen mode

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] });
        });
    });
};


Enter fullscreen mode Exit fullscreen mode
  • 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:

<form action="/reset-password" method="POST">
    <input type="hidden" name="email" value="<%= user.email %>" />
    <label>New Password:</label>
    <input type="password" name="password" required />
    <button type="submit">Reset Password</button>
</form>
Enter fullscreen mode Exit fullscreen mode

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.' });
        });
    });
});

Enter fullscreen mode Exit fullscreen mode
  • 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) { %>
    <h2><%= message %></h2>
<% } %>
Enter fullscreen mode Exit fullscreen mode

6. Running the Server

Start the Node.js server:

node index.js
Enter fullscreen mode Exit fullscreen mode

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.

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay