Sunday, 23 March 2025

Building a Simple JWT Authentication System with Express: A Beginner's Guide

In this tutorial, we'll walk through creating a JWT authentication system using Express.js. JWT (JSON Web Tokens) is a powerful tool for securely transmitting information between parties, and it's widely used in modern web applications for authentication.

What is JWT Authentication?


JWT (JSON Web Token) is an open standard for securely transmitting information between parties as a JSON object. It is commonly used in web applications to authenticate users and allow them to access protected resources.

In simple terms:

  1. JWT provides a way to authenticate users by generating a token after they log in.
  2. This token can then be used to access protected resources.
  3. The token is signed with a secret key, which ensures that the token has not been tampered with.

In this guide, we'll build a simple Express.js application that:

  • Allows users to log in and receive a JWT.
  • Protects certain routes using that JWT.

Let's dive in!




What Will We Build?

We'll create a simple Express.js server with the following features:

  1. Login route: A POST route where users submit their username and password to receive a JWT.
  2. Protected route: A GET route that requires a valid JWT to access.

Prerequisites

Before we begin, ensure you have the following:

  1. Node.js installed on your computer (download it here).
  2. A basic understanding of JavaScript and Express.js.

Step 1: Setting Up the Project

Let’s start by setting up a new Node.js project.

  1. Create a new directory for your project:

    Open your terminal/command prompt and create a new folder:

    mkdir jwt-auth-example
    cd jwt-auth-example
    
  2. Initialize the Node.js project:

    Run the following command to create a package.json file:

    npm init -y
    
  3. Install the necessary dependencies:

    We need three libraries:

    • express: The web framework for building our server.
    • jsonwebtoken: A library to create and verify JWTs.
    • dotenv: A library to manage environment variables securely.

    Install them using npm:

    npm install express jsonwebtoken dotenv
    

Step 2: Writing the Server Code

Now, let’s write the code for the Express server.

  1. Create a file named index.js in the root of your project.
  2. Add the following code to handle JWT authentication:
// Import necessary packages
const express = require('express');
const jwt = require('jsonwebtoken');
const dotenv = require('dotenv');

// Load environment variables from .env file
dotenv.config();

const app = express();
const port = 3000;

// Middleware to parse JSON request bodies
app.use(express.json());

// Secret key for signing JWTs (should be in .env file for security)
const SECRET_KEY = process.env.JWT_SECRET || 'your_jwt_secret_key';

// Dummy user data for demonstration (In a real app, you would query a database)
const users = [
  { id: 1, username: 'john_doe', password: 'password123' },
  { id: 2, username: 'jane_doe', password: 'securepassword' }
];

// Route for user login
app.post('/login', (req, res) => {
  const { username, password } = req.body;

  // Check if the user exists and if the password is correct
  const user = users.find(u => u.username === username && u.password === password);
  
  if (!user) {
    return res.status(401).json({ message: 'Invalid credentials' });
  }

  // Create a JWT token
  const token = jwt.sign(
    { id: user.id, username: user.username },
    SECRET_KEY,
    { expiresIn: '1h' } // Token will expire in 1 hour
  );

  res.json({ message: 'Login successful', token });
});

// Middleware to verify JWT token
const verifyToken = (req, res, next) => {
  const token = req.header('Authorization')?.replace('Bearer ', '');

  if (!token) {
    return res.status(403).json({ message: 'Access denied. No token provided.' });
  }

  jwt.verify(token, SECRET_KEY, (err, decoded) => {
    if (err) {
      return res.status(403).json({ message: 'Invalid token' });
    }
    req.user = decoded; // Attach user info to the request
    next(); // Proceed to the next middleware or route handler
  });
};

// Protected route that requires a valid JWT
app.get('/protected', verifyToken, (req, res) => {
  res.json({ message: `Welcome ${req.user.username}, you have access to this protected route!` });
});

// Start the server
app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
});

Step 3: Set Up Environment Variables

For security purposes, we don't want to expose our secret key directly in the code. Instead, we’ll store it in an environment variable using the dotenv package.

  1. Create a .env file in the root of your project.
  2. Add the following line to the .env file to store your secret key:
JWT_SECRET=your_jwt_secret_key

Replace your_jwt_secret_key with a strong, secret key. This key will be used to sign and verify JWT tokens.


Step 4: Testing the API

1. Login Endpoint (/login)

First, let’s test the login functionality. To log in, you need to send a POST request to the /login route with the following body:

{
  "username": "john_doe",
  "password": "password123"
}

If the credentials are correct, the response will contain a JWT token:

Response:

{
  "message": "Login successful",
  "token": "your_jwt_token_here"
}

2. Accessing the Protected Route (/protected)

Now that we have a token, we can access the protected route /protected. To do this, include the token in the Authorization header as a Bearer token.

Request:

GET http://localhost:3000/protected
Authorization: Bearer your_jwt_token_here

If the token is valid, the response will be:

{
  "message": "Welcome john_doe, you have access to this protected route!"
}

If the token is invalid or missing, you’ll get an error message like:

{
  "message": "Invalid token"
}

Step 5: Running the Server

To run the server, use the following command in your terminal:

node index.js

Your server will start running on http://localhost:3000

Saturday, 15 March 2025

MongoDB Integration with Express: A Step-by-Step Guide to CRUD Operations Using Mongoose

MongoDB is a powerful NoSQL database, and integrating it with an Express.js application is made easy with Mongoose. In this guide, we'll go through the step-by-step process of setting up MongoDB, installing Mongoose, defining a schema, and performing CRUD operations.





1. Install MongoDB Compass

MongoDB Compass is a graphical user interface (GUI) for managing MongoDB databases. You can download and install it from the official website:

🔗 Download MongoDB Compass

Once installed, you can use it to visualize and manage your database.




2. Install Mongoose

Mongoose is an Object Data Modeling (ODM) library for MongoDB, making it easier to interact with the database. To install it, run the following command in your project directory:

npm i mongoose



3. Define the Database and Collection in Mongoose

Now, create a new file named user.js in your project directory. This file will define the database connection and schema.

const mongoose = require("mongoose");

// Connect to MongoDB (Make sure MongoDB is running locally)
mongoose.connect("mongodb://127.0.0.1:27017/data1", {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

// Define schema for the collection
const userSchema = mongoose.Schema({
    username: String,
    name: String,
    age: Number
});

// Export the model
module.exports = mongoose.model("student", userSchema);

4. Perform CRUD Operations in Express.js

Now, let's integrate MongoDB operations in the index.js file using Express.

a. Create a User (Insert Data)

This route creates a new user in the database.

const express = require('express');
const router = express.Router();
const userModel = require('./user'); // Import the user model

router.get('/', async function(req, res) {
    const user = await userModel.create({
        username: "Asma",
        age: 33,
        name: "Asma"
    });

    res.send(user);
});

b. Find a User (Retrieve Data)

This route fetches a user with a specific name.

router.get('/userone', async function(req, res) {
    let user = await userModel.findOne({ name: "mahine" });
    res.send(user);
});

c. Delete a User

This route deletes a user with a specific name.

router.get('/delete', async function(req, res) {
    let deletedUser = await userModel.findOneAndDelete({ name: "mahine" });
    res.send(deletedUser);
});

5. Checking the Database Updates

After adding, retrieving, or deleting users, you can check your MongoDB Compass to see the changes reflected in the data1 database under the students collection.


6. Running the Application

To run the application, first, install nodemon if you haven't already:

npm i -g nodemon

Now, start the server:

npx nodemon index.js

7. Testing the CRUD Operations

Open your browser or use Postman to test the following endpoints:

  1. Create a user:
    http://localhost:3000/
    
  2. Find a user:
    http://localhost:3000/userone
    
  3. Delete a user:
    http://localhost:3000/delete
    


Managing Sessions in Express.js with express-session

Managing user sessions is a fundamental aspect of web development, especially when dealing with authentication and user state management. In this guide, we'll explore how to use express-session in an Express.js application to store and retrieve session data.




1. What is express-session?

express-session is a middleware for Express.js that enables session management by storing session data on the server-side. This is useful for tracking user activities, authentication, and managing temporary data between requests.


2. Installing express-session

To get started, install the express-session package using npm:

bash

npm i express-session

3. Configuring express-session in Your App

First, require express-session in your main application file (e.g., app.js) and configure it as middleware:

javascript

const express = require('express'); const session = require('express-session'); const app = express(); // Configure session middleware app.use(session({ secret: "gggggghhhhhh", // Secret key for signing the session ID resave: false, // Prevents resaving session if nothing has changed saveUninitialized: false // Prevents saving uninitialized sessions })); app.use(express.json());

4. Setting and Retrieving Session Data in Routes

Now, let's create a route file (routes/sessionRoutes.js) to set and retrieve session values.

Setting Session Data

In the following route, we set session variables:

javascript

const express = require('express'); const router = express.Router(); router.get('/', (req, res) => { req.session.name = "hello"; req.session.ban = true; res.send("Session data set."); });

Retrieving Session Data

To access and check session data, we create another route:

javascript

router.get('/sessions', (req, res) => { console.log(req.session); // Logs session data to the console res.send(`Session Data: ${JSON.stringify(req.session)}`); }); module.exports = router;

5. Integrating Routes in the App

Now, include these session routes in your main application (app.js):

javascript

const sessionRoutes = require('./routes/sessionRoutes'); app.use('/session', sessionRoutes);

6. Running the Application

Run the application using:

bash

node app.js

Testing the Endpoints

  1. Set session data:
    Open your browser or use Postman and visit:

    bash

    http://localhost:3000/session/

    This will set session values.

  2. Retrieve session data:
    Visit:

    bash

    http://localhost:3000/session/sessions

    This will display the stored session data.