Authentication is a crucial aspect of web development, ensuring that users are who they claim to be. In this section, we will cover the basics of authentication, its importance, and how it is implemented in Node.js applications.

Key Concepts

  1. Authentication vs. Authorization:

    • Authentication: The process of verifying the identity of a user.
    • Authorization: The process of determining what an authenticated user is allowed to do.
  2. Types of Authentication:

    • Basic Authentication: Uses a username and password.
    • Token-Based Authentication: Uses tokens (e.g., JWT) to authenticate users.
    • OAuth: An open standard for access delegation, commonly used for token-based authentication.
  3. Common Authentication Methods:

    • Session-Based Authentication: Stores user information on the server.
    • Token-Based Authentication: Stores user information in a token, typically a JSON Web Token (JWT).

Practical Example: Basic Authentication

Step 1: Setting Up the Project

  1. Initialize a new Node.js project:

    mkdir auth-example
    cd auth-example
    npm init -y
    
  2. Install necessary packages:

    npm install express body-parser
    
  3. Create the project structure:

    auth-example/
    ├── node_modules/
    ├── package.json
    ├── server.js
    └── users.js
    

Step 2: Implementing Basic Authentication

  1. Create a users.js file to store user data:

    // users.js
    const users = [
      { id: 1, username: 'user1', password: 'password1' },
      { id: 2, username: 'user2', password: 'password2' }
    ];
    
    module.exports = users;
    
  2. Create a server.js file to set up the server and authentication logic:

    // server.js
    const express = require('express');
    const bodyParser = require('body-parser');
    const users = require('./users');
    
    const app = express();
    app.use(bodyParser.json());
    
    // Basic Authentication Middleware
    const authenticate = (req, res, next) => {
      const { username, password } = req.body;
      const user = users.find(u => u.username === username && u.password === password);
    
      if (user) {
        req.user = user;
        next();
      } else {
        res.status(401).send('Authentication failed');
      }
    };
    
    // Protected Route
    app.post('/login', authenticate, (req, res) => {
      res.send(`Welcome ${req.user.username}`);
    });
    
    // Start the server
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => {
      console.log(`Server is running on port ${PORT}`);
    });
    

Step 3: Testing the Authentication

  1. Start the server:

    node server.js
    
  2. Test the authentication using a tool like Postman:

    • Endpoint: POST http://localhost:3000/login

    • Body:

      {
        "username": "user1",
        "password": "password1"
      }
      
    • Expected Response:

      Welcome user1
      

Practical Exercise

Exercise: Implement Token-Based Authentication

  1. Install the necessary packages:

    npm install jsonwebtoken
    
  2. Modify the server.js file to use JWT for authentication:

    // server.js
    const express = require('express');
    const bodyParser = require('body-parser');
    const jwt = require('jsonwebtoken');
    const users = require('./users');
    
    const app = express();
    app.use(bodyParser.json());
    
    const SECRET_KEY = 'your_secret_key';
    
    // Token Generation
    const generateToken = (user) => {
      return jwt.sign({ id: user.id, username: user.username }, SECRET_KEY, { expiresIn: '1h' });
    };
    
    // Token Verification Middleware
    const verifyToken = (req, res, next) => {
      const token = req.headers['authorization'];
      if (!token) return res.status(403).send('Token is required');
    
      jwt.verify(token, SECRET_KEY, (err, decoded) => {
        if (err) return res.status(401).send('Invalid token');
        req.user = decoded;
        next();
      });
    };
    
    // Login Route
    app.post('/login', (req, res) => {
      const { username, password } = req.body;
      const user = users.find(u => u.username === username && u.password === password);
    
      if (user) {
        const token = generateToken(user);
        res.json({ token });
      } else {
        res.status(401).send('Authentication failed');
      }
    });
    
    // Protected Route
    app.get('/protected', verifyToken, (req, res) => {
      res.send(`Welcome ${req.user.username}`);
    });
    
    // Start the server
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => {
      console.log(`Server is running on port ${PORT}`);
    });
    
  3. Test the token-based authentication:

    • Login:

      • Endpoint: POST http://localhost:3000/login
      • Body:
        {
          "username": "user1",
          "password": "password1"
        }
        
      • Expected Response:
        {
          "token": "your_jwt_token"
        }
        
    • Access Protected Route:

      • Endpoint: GET http://localhost:3000/protected
      • Headers:
        Authorization: your_jwt_token
        
      • Expected Response:
        Welcome user1
        

Summary

In this section, we covered the basics of authentication, including the difference between authentication and authorization, common authentication methods, and practical examples of implementing basic and token-based authentication in a Node.js application. Understanding these concepts is crucial for building secure web applications. In the next section, we will delve deeper into using Passport.js for more advanced authentication strategies.

Node.js Course

Module 1: Introduction to Node.js

Module 2: Core Concepts

Module 3: File System and I/O

Module 4: HTTP and Web Servers

Module 5: NPM and Package Management

Module 6: Express.js Framework

Module 7: Databases and ORMs

Module 8: Authentication and Authorization

Module 9: Testing and Debugging

Module 10: Advanced Topics

Module 11: Deployment and DevOps

Module 12: Real-World Projects

© Copyright 2024. All rights reserved