Introduction

Authentication is a crucial part of web applications, ensuring users can securely log in and manage their accounts. In this blog post, I have provided you an overview of how things work, and I also mentioned my GitHub repo for a better understanding of the code. You can take a quick overview of the project on Try Out. I will share how I built an authentication system using Node.js, Express, and various useful packages.

Refer to this Github Repo

Features of the Authentication App

  • Secure password encryption with bcrypt
  • JSON Web Token (JWT) authentication using jsonwebtoken and passport-jwt
  • Role-based access control via accesscontrol
  • Cookie management with cookie-parser
  • Email verification and password reset functionality with nodemailer and mailgen
  • File uploads using multer
  • MongoDB database integration with mongoose
  • Environment variable management using dotenv
  • Enhanced API security through cors and validator
I have designed this project so that it can be used as starter code for any application. It includes role-based access control, which is commonly required in CRMs, along with integrated email services. I have also ensured that each method and function is reusable, following the DRY (Don't Repeat Yourself) principle to keep the code efficient and maintainable.

Project Structure

server/
│   server.js            # Main server file
│   .env                 # Environment variables
│   package.json         # Project dependencies and scripts
│
ā”œā”€ā”€ config/
│   ā”œā”€ā”€ db.js            # Database connection setup
│   ā”œā”€ā”€ passport.js      # Passport authentication setup
│
ā”œā”€ā”€ models/
│   ā”œā”€ā”€ User.js          # User schema definition
│
ā”œā”€ā”€ routes/
│   ā”œā”€ā”€ authRoutes.js    # Routes for authentication
│   ā”œā”€ā”€ userRoutes.js    # Routes for user actions
│
ā”œā”€ā”€ controllers/
│   ā”œā”€ā”€ authController.js  # Handles authentication logic
│   ā”œā”€ā”€ userController.js  # Manages user operations
│
ā”œā”€ā”€ middleware/
│   ā”œā”€ā”€ authMiddleware.js  # Middleware for authentication
│
ā”œā”€ā”€ utils/
│   ā”œā”€ā”€ mailer.js        # Email handling logic
│
└── uploads/             # Storage for uploaded files

Implementation Overview

1. User Registration

const bcrypt = require('bcrypt');
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);

Security is key. It is crucial to hash the password before saving it to the database. In the code above I explain you about how to hashed your password using bcrypt.

2. JWT Authentication

const jwt = require('jsonwebtoken');
const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });

In this code snippet, we are using jsonwebtoken to generate a token for user authentication. The token is created with the jwt.sign() method, which takes a payload (here, userId: user._id) and a secret key (process.env.JWT_SECRET) to securely sign the token. The token is set to expire in 1 hour (expiresIn: '1h'), after which the user will need to re-authenticate.

What is JSON Web Token (JWT)?

JWT (JSON Web Token) is a compact, URL-safe token used for securely transmitting information between parties as a JSON object. It's commonly used for authentication, where the server generates a token for a user upon login, and the user sends this token in subsequent requests to prove their identity. JWTs consist of three parts: the header, payload, and signature, which together ensure the integrity and authenticity of the information.

3. Role-Based Access Control

const ac = new AccessControl();
ac.grant('user').readOwn('profile');
ac.grant('admin').extend('user').updateAny('profile');

Deployment

"scripts": {
  "start": "node server.js",
  "dev": "nodemon server.js"
}