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.

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.