DEV Community

Cover image for Role-Based Authentication in Node.js with Express.js and MongoDB
Haque.
Haque.

Posted on

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

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

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

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

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

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

Use Postman or cURL to test:

  1. Register a user: POST /api/auth/register
  2. Login to receive a token: POST /api/auth/login
  3. Get a new access token: POST /api/auth/refresh
  4. Change user role (Admin only): PUT /api/auth/change-role/:id
  5. Access protected routes:
  6. GET /api/protected/admin (Admin only)
  7. 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

Top comments (0)