Role-Based Authentication in Node.js with Express.js and MongoDB
Introduction Role-Based Authentication (RBA) is a method to control access based on user roles (e.g., Admin, User, Manager). This tutorial will guide you through implementing RBA in a Node.js application using Express.js and MongoDB. Prerequisites Before we start, ensure you have the following: Node.js installed on your system MongoDB set up and running Basic knowledge of Express.js and JWT (JSON Web Tokens) A tool like Postman or cURL for API testing Steps to Implement Role-Based Authentication 1. Initialize the Project First, create a new project folder and initialize a Node.js project. mkdir role-based-auth cd role-based-auth npm init -y This creates a package.json file for managing dependencies. Now, install the required packages: npm install express mongoose bcryptjs jsonwebtoken dotenv cors express-rate-limit https express: Web framework for Node.js mongoose: ODM (Object Data Modeling) library for MongoDB bcryptjs: For hashing passwords securely jsonwebtoken: To generate and verify authentication tokens dotenv: For managing environment variables cors: To enable Cross-Origin Resource Sharing express-rate-limit: To prevent API abuse https: For secure HTTPS implementation 2. Set Up the Server Create server.js and configure the Express server: require('dotenv').config(); const express = require('express'); const mongoose = require('mongoose'); const fs = require('fs'); const https = require('https'); const rateLimit = require('express-rate-limit'); const authRoutes = require('./routes/authRoutes'); const protectedRoutes = require('./routes/protectedRoutes'); const app = express(); app.use(express.json()); app.use('/api/auth', authRoutes); app.use('/api/protected', protectedRoutes); // Rate Limiting const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // Limit each IP to 100 requests per window message: 'Too many requests, please try again later.' }); app.use(limiter); mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true, }).then(() => console.log("MongoDB Connected")) .catch(err => console.error(err)); const httpsOptions = { key: fs.readFileSync('./key.pem'), cert: fs.readFileSync('./cert.pem') }; https.createServer(httpsOptions, app).listen(5000, () => console.log('Server running on port 5000 (HTTPS)')); 3. Implement Refresh Tokens Modify routes/authRoutes.js to include refresh tokens: const jwt = require('jsonwebtoken'); const refreshTokens = []; // Generate Access Token const generateAccessToken = (user) => { return jwt.sign({ id: user._id, role: user.role }, process.env.JWT_SECRET, { expiresIn: '15m' }); }; // Generate Refresh Token const generateRefreshToken = (user) => { const refreshToken = jwt.sign({ id: user._id }, process.env.REFRESH_SECRET); refreshTokens.push(refreshToken); return refreshToken; }; // Refresh Token Route router.post('/refresh', (req, res) => { const { token } = req.body; if (!token || !refreshTokens.includes(token)) { return res.status(403).json({ message: 'Access denied' }); } jwt.verify(token, process.env.REFRESH_SECRET, (err, user) => { if (err) return res.status(403).json({ message: 'Invalid refresh token' }); const accessToken = generateAccessToken(user); res.json({ accessToken }); }); }); 4. Implement Role Management Modify routes/authRoutes.js to allow admin to change user roles: const { authenticate, authorize } = require('../middleware/authMiddleware'); // Change User Role (Admin Only) router.put('/change-role/:id', authenticate, authorize(['admin']), async (req, res) => { try { const { role } = req.body; const user = await User.findByIdAndUpdate(req.params.id, { role }, { new: true }); res.json({ message: 'User role updated', user }); } catch (err) { res.status(500).json({ error: 'Server error' }); } }); 5. Secure the API with HTTPS & Rate Limiting HTTPS: Uses SSL/TLS encryption Rate Limiting: Limits requests per IP 6. Test the API Start the server: node server.js Use Postman or cURL to test: Register a user: POST /api/auth/register Login to receive a token: POST /api/auth/login Get a new access token: POST /api/auth/refresh Change user role (Admin only): PUT /api/auth/change-role/:id Access protected routes: GET /api/protected/admin (Admin only) GET /api/protected/user (User and Admin) Conclusion You have successfully implemented Role-Based Authentication in Node.js Express with MongoDB. Key Features: ✔ Refresh tokens for session management ✔ Dynamic role management ✔ API security with HTTPS & rate limiting

Introduction
Role-Based Authentication (RBA) is a method to control access based on user roles (e.g., Admin, User, Manager). This tutorial will guide you through implementing RBA in a Node.js application using Express.js and MongoDB.
Prerequisites
Before we start, ensure you have the following:
- Node.js installed on your system
- MongoDB set up and running
- Basic knowledge of Express.js and JWT (JSON Web Tokens)
- A tool like Postman or cURL for API testing
Steps to Implement Role-Based Authentication
1. Initialize the Project
First, create a new project folder and initialize a Node.js project.
mkdir role-based-auth
cd role-based-auth
npm init -y
This creates a package.json
file for managing dependencies.
Now, install the required packages:
npm install express mongoose bcryptjs jsonwebtoken dotenv cors express-rate-limit https
express
: Web framework for Node.js
mongoose
: ODM (Object Data Modeling) library for MongoDB
bcryptjs
: For hashing passwords securely
jsonwebtoken
: To generate and verify authentication tokens
dotenv
: For managing environment variables
cors
: To enable Cross-Origin Resource Sharing
express-rate-limit
: To prevent API abuse
https
: For secure HTTPS implementation
2. Set Up the Server
Create server.js
and configure the Express server:
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const fs = require('fs');
const https = require('https');
const rateLimit = require('express-rate-limit');
const authRoutes = require('./routes/authRoutes');
const protectedRoutes = require('./routes/protectedRoutes');
const app = express();
app.use(express.json());
app.use('/api/auth', authRoutes);
app.use('/api/protected', protectedRoutes);
// Rate Limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Limit each IP to 100 requests per window
message: 'Too many requests, please try again later.'
});
app.use(limiter);
mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(() => console.log("MongoDB Connected"))
.catch(err => console.error(err));
const httpsOptions = {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem')
};
https.createServer(httpsOptions, app).listen(5000, () => console.log('Server running on port 5000 (HTTPS)'));
3. Implement Refresh Tokens
Modify routes/authRoutes.js
to include refresh tokens:
const jwt = require('jsonwebtoken');
const refreshTokens = [];
// Generate Access Token
const generateAccessToken = (user) => {
return jwt.sign({ id: user._id, role: user.role }, process.env.JWT_SECRET, { expiresIn: '15m' });
};
// Generate Refresh Token
const generateRefreshToken = (user) => {
const refreshToken = jwt.sign({ id: user._id }, process.env.REFRESH_SECRET);
refreshTokens.push(refreshToken);
return refreshToken;
};
// Refresh Token Route
router.post('/refresh', (req, res) => {
const { token } = req.body;
if (!token || !refreshTokens.includes(token)) {
return res.status(403).json({ message: 'Access denied' });
}
jwt.verify(token, process.env.REFRESH_SECRET, (err, user) => {
if (err) return res.status(403).json({ message: 'Invalid refresh token' });
const accessToken = generateAccessToken(user);
res.json({ accessToken });
});
});
4. Implement Role Management
Modify routes/authRoutes.js
to allow admin to change user roles:
const { authenticate, authorize } = require('../middleware/authMiddleware');
// Change User Role (Admin Only)
router.put('/change-role/:id', authenticate, authorize(['admin']), async (req, res) => {
try {
const { role } = req.body;
const user = await User.findByIdAndUpdate(req.params.id, { role }, { new: true });
res.json({ message: 'User role updated', user });
} catch (err) {
res.status(500).json({ error: 'Server error' });
}
});
5. Secure the API with HTTPS & Rate Limiting
- HTTPS: Uses SSL/TLS encryption
- Rate Limiting: Limits requests per IP
6. Test the API
Start the server:
node server.js
Use Postman or cURL to test:
- Register a user: POST /api/auth/register
- Login to receive a token: POST /api/auth/login
- Get a new access token: POST /api/auth/refresh
- Change user role (Admin only): PUT /api/auth/change-role/:id
- Access protected routes:
- GET /api/protected/admin (Admin only)
- GET /api/protected/user (User and Admin)
Conclusion
You have successfully implemented Role-Based Authentication in Node.js Express with MongoDB.
Key Features:
✔ Refresh tokens for session management
✔ Dynamic role management
✔ API security with HTTPS & rate limiting