logologo
  • AI Tools

    DB Query GeneratorMock InterviewResume BuilderLearning Path GeneratorCheatsheet GeneratorAgentic Prompt GeneratorCompany ResearchCover Letter Generator
  • XpertoAI
  • MVP Ready
  • Resources

    CertificationsTopicsExpertsCollectionsArticlesQuestionsVideosJobs
logologo

Elevate Your Coding with our comprehensive articles and niche collections.

Useful Links

  • Contact Us
  • Privacy Policy
  • Terms & Conditions
  • Refund & Cancellation
  • About Us

Resources

  • Xperto-AI
  • Certifications
  • Python
  • GenAI
  • Machine Learning

Interviews

  • DSA
  • System Design
  • Design Patterns
  • Frontend System Design
  • ReactJS

Procodebase © 2024. All rights reserved.

Level Up Your Skills with Xperto-AI

A multi-AI agent platform that helps you level up your development skills and ace your interview preparation to secure your dream job.

Launch Xperto-AI

Securing Your Node.js Application with JWT Authentication

author
Generated by
Abhishek Goyan

14/10/2024

Node.js

Sign in to read full article

In today's digital landscape, ensuring the security of your application is paramount, especially when dealing with user data. One method that has emerged as a robust solution for securing APIs is JSON Web Token (JWT) authentication. In this blog post, we will explore how to implement JWT authentication in a Node.js application as part of our CRUD app with MongoDB and TypeScript.

Understanding JWT

Before we jump into implementation, let’s clarify what JWT is. JSON Web Tokens are an open standard used to share security information between two parties. This transfer is compact, URL-safe, and can be verified and trusted since it is digitally signed.

A JWT consists of three parts:

  1. Header: Indicates the type of token and the signing algorithm being used (typically HMAC SHA256).
  2. Payload: Contains the claims, which are the information we want to store (typically user ID, roles, and other user-specific data).
  3. Signature: Ensures that the token is not altered. It is formed by combining the encoded header, encoded payload, and a secret key.

Let’s break that down further in the context of our CRUD application.

Setting Up Your Node.js Environment

To follow along, ensure you have Node.js installed, and you're working in a project set up with TypeScript. You can initialize your project with:

mkdir my-crud-app cd my-crud-app npm init -y npm install express mongoose jsonwebtoken bcryptjs dotenv npm install --save-dev typescript @types/node @types/express @types/mongoose @types/jsonwebtoken @types/bcryptjs

Also, don't forget to set up your tsconfig.json.

Identity Management: User Model

First, let’s create a user model. In your models directory, create a file named User.ts:

import mongoose, { Schema, Document } from 'mongoose'; export interface IUser extends Document { username: string; password: string; } const UserSchema: Schema = new Schema({ username: { type: String, required: true, unique: true }, password: { type: String, required: true } }); export const User = mongoose.model<IUser>('User', UserSchema);

In our user model, we are defining a simple schema that consists of a username and password.

Registering a User

Now we need to create a route to register users. Create a file named auth.ts in your routes directory:

import express from 'express'; import bcrypt from 'bcryptjs'; import { User } from '../models/User'; import jwt from 'jsonwebtoken'; const router = express.Router(); router.post('/register', async (req, res) => { try { const { username, password } = req.body; // Check if user already exists const existingUser = await User.findOne({ username }); if (existingUser) { return res.status(400).json({ message: 'User already exists' }); } const hashedPassword = await bcrypt.hash(password, 10); const user = new User({ username, password: hashedPassword }); await user.save(); // Generate JWT token const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET || 'your_secret', { expiresIn: '1h' }); res.status(201).json({ token }); } catch (error) { res.status(500).json({ message: 'Server error' }); } }); export default router;

Explanation

  • We import necessary packages like bcryptjs for hashing passwords and jsonwebtoken for creating JWTs.
  • We create a new user after checking if the user already exists.
  • Upon successful registration, we return a JWT token, which can be used for subsequent requests.

Authenticating a User

Next, let’s create a route to authenticate a user. We’ll extend our auth.ts file:

router.post('/login', async (req, res) => { const { username, password } = req.body; const user = await User.findOne({ username }); if (!user || !(await bcrypt.compare(password, user.password))) { return res.status(401).json({ message: 'Invalid credentials' }); } const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET || 'your_secret', { expiresIn: '1h' }); res.json({ token }); });

Explanation

  • In the login route, we check the user's credentials against the database and compare the hash with the provided password.
  • If valid, we generate a JWT token and send it back to the client.

Protecting Routes with JWT Middleware

Now, we need to protect certain routes. Create a middleware function that verifies the JWT token:

import { Request, Response, NextFunction } from 'express'; import jwt from 'jsonwebtoken'; export const verifyToken = (req: Request, res: Response, next: NextFunction) => { const token = req.headers['authorization']?.split(' ')[1]; if (!token) { return res.status(403).json({ message: 'Access denied' }); } jwt.verify(token, process.env.JWT_SECRET || 'your_secret', (err, decoded) => { if (err) { return res.status(401).json({ message: 'Invalid token' }); } // Add user information to the request for further usage req.user = decoded; next(); }); };

Explanation

  • This middleware checks for the JWT in the Authorization header.
  • If valid, it adds the decoded user information to the request object for further use in subsequent middleware or route handlers.

Example: Securing a Protected Route

Let’s create a protected route for retrieving user information in your routes directory:

router.get('/user', verifyToken, (req, res) => { res.json({ id: req.user.id, username: req.user.username }); });

Explanation

  • This route uses the verifyToken middleware to ensure only authenticated users can access it. If the token is valid, the user’s information is sent back.

Final Steps

To complete the implementation, don’t forget to initialize your Express app and connect to MongoDB:

import express from 'express'; import mongoose from 'mongoose'; import dotenv from 'dotenv'; import authRoutes from './routes/auth'; dotenv.config(); const app = express(); app.use(express.json()); mongoose.connect(process.env.MONGODB_URI || 'your_mongodb_uri', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('MongoDB connected')) .catch(err => console.log(err)); app.use('/auth', authRoutes); app.listen(5000, () => console.log('Server running on port 5000'));

Explanation

  • We set up the Express app, connect to MongoDB, and include our authentication routes to handle registration and login.

Implementing JWT authentication not only secures your application but also creates a scalable and practical way of managing user sessions. With this framework, you can further enhance your CRUD application with secure access controls and protect your user data effectively.

Popular Tags

Node.jsJWTAuthentication

Share now!

Like & Bookmark!

Related Collections

  • Optimising Backend APIs - Node.js

    31/08/2024 | NodeJS

  • Node.js Mastery: From Foundations to Frontiers

    08/10/2024 | NodeJS

  • Build a CRUD App with Node.js, MongoDB, and TypeScript

    14/10/2024 | NodeJS

Related Articles

  • Optimizing Database Queries in Node.js

    31/08/2024 | NodeJS

  • Testing CRUD Operations in Your Node.js Application

    14/10/2024 | NodeJS

  • Harnessing the Power of the Routing-Controllers Package in Node.js

    28/11/2024 | NodeJS

  • Installing and Configuring Dependencies for Node.js - A Step-by-Step Guide

    14/10/2024 | NodeJS

  • Implementing RabbitMQ with Node.js

    18/09/2024 | NodeJS

  • Connecting to MongoDB with Mongoose

    14/10/2024 | NodeJS

  • Setting Up Your Development Environment for Node.js

    14/10/2024 | NodeJS

Popular Category

  • Python
  • Generative AI
  • Machine Learning
  • ReactJS
  • System Design