Building a Secure Authentication System with Node.js and Express With Email Service

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
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"
}