full-stack-authn-example

πŸ” JWT Authentication Learning Demo

A comprehensive, educational Express.js application that demonstrates JWT (JSON Web Token) authentication concepts with MongoDB integration.

Environment Setup

Include in yoru .env file in the root directory:

# MongoDB connection string from MongoDB Atlas
MONGO_URI=mongodb+srv://username:password@cluster.mongodb.net/?retryWrites=true&w=majority

# JWT Secret Key - GENERATE A NEW ONE FOR PRODUCTION!
# You can generate a secure secret with this command:
# node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
JWT_SECRET=your-super-secret-jwt-key-here-make-it-long-and-random

# Optional: Set port (defaults to 3000)
PORT=3000

πŸ›‘οΈ Security Concepts Covered

πŸ—‚οΈ Project Structure

β”œβ”€β”€ app.mjs                 # Main server with detailed JWT education
β”œβ”€β”€ package.json           # Dependencies and scripts
β”œβ”€β”€ .env.example          # Environment variable template
└── public/               # Frontend files
    β”œβ”€β”€ index.html        # Landing page
    β”œβ”€β”€ auth.html         # Authentication interface
    β”œβ”€β”€ protected-demo.html # Protected route demonstration
    β”œβ”€β”€ student-crud.html # Authenticated CRUD operations
    β”œβ”€β”€ styles/           # Organized CSS files
    β”‚   β”œβ”€β”€ auth.css
    β”‚   β”œβ”€β”€ index.css
    β”‚   β”œβ”€β”€ protected-demo.css
    β”‚   └── student-crud.css
    └── scripts/          # Organized JavaScript files
        β”œβ”€β”€ auth.js
        β”œβ”€β”€ index.js
        β”œβ”€β”€ protected-demo.js
        └── student-crud.js

πŸ”‘ Authentication Flow Explained

1. User Registration

// What happens when a user registers:
POST /api/auth/register
{
  "username": "student123",
  "password": "mypassword"
}

// Server process:
1. Validates input (username exists, password length)
2. Checks if username is already taken
3. Hashes password with bcrypt (NEVER store plain passwords!)
4. Saves user to MongoDB
5. Returns success message

2. User Login & Token Creation

// What happens when a user logs in:
POST /api/auth/login
{
  "username": "student123", 
  "password": "mypassword"
}

// Server process:
1. Finds user in database
2. Compares provided password with stored hash using bcrypt
3. If valid, creates JWT token with user info
4. Returns token to client

// JWT Token Structure (3 parts):
// header.payload.signature
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2M...

3. Accessing Protected Routes

// Client sends token in Authorization header:
GET /api/auth/me
Headers: {
  "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

// Server middleware process:
1. Extracts token from "Bearer TOKEN" format
2. Verifies token signature using JWT_SECRET
3. Checks if token is expired
4. If valid, adds user info to req.user
5. Calls next() to continue to route handler

πŸ›‘οΈ Security Best Practices Demonstrated

Password Security

JWT Security

Input Validation

πŸ”§ How to Generate JWT Secrets

Method 1: Node.js Command Line

node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"

Method 2: Online Generator

Visit: https://jwt.io/ and use their secret generator

Method 3: OpenSSL Command

openssl rand -hex 64

Important:

πŸŽ“ Advanced Concepts to Explore

Token Refresh Patterns

Role-Based Authorization (authZ)

Password Reset Flow

Environment-Specific Security

πŸ› Common Issues & Solutions

β€œFailed to connect to MongoDB”

β€œInvalid token” errors

CORS issues (if building separate frontend)

// Add CORS middleware if needed:
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
  next();
});

πŸ“– Additional Resources