Contact Us
Email: info@mohitdesigns.com
Mobile: +91-9718991639
Contact Us
Email: info@mohitdesigns.com
Mobile: +91-9718991639
Authentication is a cornerstone of modern web applications, ensuring secure user access to systems. If you’re building an Auth API with Node.js and MongoDB, this guide will walk you through the process step-by-step. By the end, you’ll have a secure, scalable, and reliable authentication system that meets modern standards.
Node.js, known for its efficiency and scalability, pairs well with MongoDB, a flexible NoSQL database. Together, they provide an excellent foundation for building robust APIs. The asynchronous nature of Node.js, combined with MongoDB’s schema-less design, enables quick and efficient development of complex authentication systems.
Before diving into coding, ensure your development environment is ready.
Run the following commands to create your project:
mkdir auth-api
cd auth-api
npm init -y
This creates a package.json
file, the core of your Node.js project.
Install the essential packages for authentication:
npm install express mongoose bcrypt jsonwebtoken dotenv
Organize your project for scalability:
auth-api/
├── controllers/
├── models/
├── routes/
├── config/
├── .env
├── server.js
Create a .env
file in the root directory and add:
PORT=5000
MONGO_URI=mongodb://localhost:27017/authDB
JWT_SECRET=your_jwt_secret_key
Load these variables using dotenv
in your application:
require('dotenv').config();
const PORT = process.env.PORT || 5000;
const MONGO_URI = process.env.MONGO_URI;
const JWT_SECRET = process.env.JWT_SECRET;
Establish a connection to the database in a config/db.js
file:
const mongoose = require('mongoose');
const connectDB = async () => {
try {
await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
console.log('MongoDB Connected...');
} catch (error) {
console.error('Error connecting to MongoDB:', error.message);
process.exit(1);
}
};
module.exports = connectDB;
Import and invoke this function in your main file (server.js
).
Create a models/User.js
file for the user schema:
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const UserSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
}, { timestamps: true });
// Hash password before saving
UserSchema.pre('save', async function (next) {
if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 10);
next();
});
module.exports = mongoose.model('User', UserSchema);
Add a routes/auth.js
file:
const express = require('express');
const { registerUser } = require('../controllers/authController');
const router = express.Router();
router.post('/register', registerUser);
module.exports = router;
In the controllers/authController.js
file:
const User = require('../models/User');
const registerUser = async (req, res) => {
const { name, email, password } = req.body;
try {
const existingUser = await User.findOne({ email });
if (existingUser) return res.status(400).json({ message: 'User already exists' });
const user = await User.create({ name, email, password });
res.status(201).json({ message: 'User registered successfully', user });
} catch (error) {
res.status(500).json({ message: 'Server Error', error: error.message });
}
};
module.exports = { registerUser };
Add a login route:
router.post('/login', loginUser);
In authController.js
:
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const loginUser = async (req, res) => {
const { email, password } = req.body;
try {
const user = await User.findOne({ email });
if (!user) return res.status(400).json({ message: 'Invalid credentials' });
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(400).json({ message: 'Invalid credentials' });
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });
res.status(200).json({ message: 'Login successful', token });
} catch (error) {
res.status(500).json({ message: 'Server Error', error: error.message });
}
};
Create an authMiddleware.js
file:
const jwt = require('jsonwebtoken');
const protect = (req, res, next) => {
const token = req.header('Authorization')?.split(' ')[1];
if (!token) return res.status(401).json({ message: 'Unauthorized' });
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
res.status(401).json({ message: 'Invalid Token' });
}
};
module.exports = protect;
Use Postman or similar tools to:
/register
endpoint./login
to get a token.Authorization
header with the token.Building an Auth API with Node.js and MongoDB ensures a secure and efficient user authentication process. By following this guide, you’ve set up a foundation for advanced features like role-based access control, multi-factor authentication, and account recovery.
Take your time to implement each step, and don’t hesitate to expand on this basic setup to suit your application’s needs. Happy coding!
Security is a critical aspect of any authentication system, and encrypting access tokens is an essential step to enhance your application’s safety. To dive deeper into why this practice is crucial and how it adds an extra layer of protection against potential vulnerabilities, check out our detailed blog post: Why Encrypting Access Tokens Should Be Your Next Security Move!. It’s packed with insights and practical tips to help you secure your APIs like a pro.