Skip to content

vijay-kumar2001/Production-Ready-Backend-API-System

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Production-Ready Backend API System

A secure, scalable, and production-style backend system built using Node.js, Express, and MongoDB, implementing hybrid authentication (JWT + Session), role-based access control, and real-world security practices.


🧠 Why This Project Exists

Most backend projects stop at:

  • Basic JWT authentication
  • Simple CRUD APIs
  • No session management or security depth

This project goes beyond that.

It is designed to demonstrate:

βœ” Real-world authentication architecture βœ” Security-first backend design βœ” Clean layered architecture βœ” Stateful session control over stateless JWT βœ” Production-ready backend practices


🌐 Live Deployment

The backend is live and deployed in production:

https://production-ready-backend-api-system.onrender.com

⚠️ Note on Cold Starts (Render Free Tier)

This project is deployed on the free tier of Render, which uses a spin-down mechanism during inactivity.

  • If the service is idle, it is automatically stopped
  • On the next incoming request, the server boots up again

πŸ‘‰ As a result:

First request may take ~30–50 seconds (cold start)  
Subsequent requests are fast and normal  

This behavior is expected in free-tier environments and does not affect functionality.


πŸ”Ή Deployment Stack

  • Hosting: Render
  • Database: MongoDB Atlas
  • Environment: Production (cloud-based)

βš™οΈ Production Behavior Notes

  • Server runs in a stateless cloud environment
  • Filesystem is ephemeral (non-persistent)
  • External dependencies (Geo DB) are handled dynamically
  • Environment variables are managed via Render dashboard

πŸš€ Getting Started

Follow these steps to run the project locally.


1. Clone the repository

git clone https://github.com/vijay-kumar2001/production-ready-backend-api-system.git
cd production-ready-backend-api-system

2. Install dependencies

npm install

3. Setup environment variables

Create a .env file in the root:

cp .env.example .env

Now update values inside .env:

DB_URL=your-mongodb-connection-string
JWT_SECRET=your-secret-key
MAXMIND_LICENSE_KEY=your_license_key

4. Setup Geo Database (Production + Local)

This project uses MaxMind GeoLite2 City database for IP-based location detection.


πŸ”Ή Local Development

You can manually download the database:

  • Visit MaxMind website
  • Download GeoLite2-City.mmdb
  • Place it in:
src/geo/

πŸ”Ή Production (Automatic Setup)

In production, the system:

βœ” Automatically downloads Geo DB at runtime  
βœ” Extracts from tar.gz archive  
βœ” Stores in correct path  
βœ” Cleans temporary files  

πŸ‘‰ This ensures:

βœ” No manual setup required  
βœ” Works across deployments  
βœ” Handles missing files automatically  

5. Start the server

npm run dev

Server will run on:

http://localhost:3020

6. Test APIs

  • Import Postman collection from /postman folder
  • Or test manually using any API client

⚠️ Important Notes

  • Ensure MongoDB is running locally or use a cloud DB
  • Do NOT commit your .env file
  • Geo database is handled automatically in production
  • Admin user is auto-seeded if enabled in config

πŸ—οΈ System Architecture

Client β†’ Middleware β†’ Controller β†’ Service β†’ Model β†’ Database

Layers Explained

Layer Responsibility
Middleware Validation, Authentication, Authorization
Controller Request/Response handling
Service Business logic + security enforcement
Model Database interaction
Utils Stateless helpers (JWT, hashing, geo)

πŸ” Hybrid Authentication System

This project uses a Hybrid Auth Model combining JWT + Sessions.

1. Access Token (Short-lived)

  • Sent via Authorization: Bearer <token>
  • Used for protected APIs
  • Stateless but short-lived for security

2. Refresh Token (Long-lived)

  • Stored in HTTP-only cookie
  • Used only for token renewal
  • Never exposed to frontend JS

3. Session Layer (Database-backed)

Each login creates a session storing:

  • sessionId
  • userId
  • IP address
  • device & user-agent
  • expiry timestamp

πŸ‘‰ This converts JWT from stateless β†’ state-aware system


πŸ” Authentication & Session Flow

Login β†’ Session Created β†’ Tokens Generated  
↓  
Access Token β†’ Used for APIs  
↓  
Expires β†’ Refresh Token Used  
↓  
New Tokens Issued + Session Extended

πŸ”„ Token Rotation (Critical Security Feature)

On every refresh:

  • Old refresh token is deleted
  • New refresh token is issued and stored
Old Token β†’ Invalid  
New Token β†’ Active

Why this matters:

βœ” Prevents replay attacks βœ” Stolen tokens become useless after one use βœ” Ensures single-use refresh tokens


⏳ Sliding Session (Session Extension)

Each valid request:

session.expiresAt = now + SESSION_EXPIRES_IN

Impact:

βœ” Prevents auto logout during activity βœ” Maintains user experience βœ” Ensures session expires only after inactivity

πŸ‘‰ This is a sliding window session mechanism


πŸ›‘οΈ Security Features

βœ… Core Protections

  • Refresh token rotation
  • Session validation on every request
  • Token type separation (access vs refresh)
  • HTTP-only cookies (XSS protection)
  • Role-based access control (RBAC)
  • Ownership validation (resource-level security)
  • Input validation & sanitization
  • Centralized error handling middleware

🚨 Attacks Prevented

Attack Protection
Replay attack Token rotation
Token reuse after theft Rotation + session
Token swapping sessionId verification
XSS token access httpOnly cookies
Privilege escalation RBAC
Horizontal access abuse owner checks
Invalid input injection validation middleware

πŸ”„ Session + Token Relationship

User β†’ Session β†’ Refresh Token β†’ Access Token
  • Session = source of truth
  • Tokens = derived credentials

⚠️ Centralized Error Handling

The system uses a custom AppError class + global error middleware.

Benefits:

βœ” Consistent error responses βœ” Clean controller/service code βœ” Separation of logic vs error formatting

Example:

{
  "message": "Invalid token",
  "status": 401
}

🧩 Key Features

πŸ” Authentication

  • Register / Login
  • Refresh token flow
  • Logout (idempotent)
  • Token rotation implemented

πŸ‘€ User System

  • Profile retrieval
  • Session inspection
  • Secure user data sanitization

πŸ‘₯ Admin Features (RBAC)

  • Get all users (admin only)
  • Get user by ID (owner/admin)
  • Update user roles (admin only)

πŸ”„ CRUD & Data Flow

  • Create β†’ register user
  • Read β†’ profile, users
  • Update β†’ role update
  • Delete β†’ logout (session + token removal)

βš™οΈ Config System

  • Centralized config object
  • Type-safe env parsing
  • Required/optional validation
  • Feature-based config separation

πŸ”„ Runtime Dependency Handling

This system implements dynamic dependency management:

πŸ”Ή Example: Geo Database

βœ” Not stored in repository  
βœ” Not manually uploaded  
βœ” Automatically downloaded on startup  
βœ” Always available when server runs  

πŸ”Ή Why this matters

βœ” Works in cloud environments  
βœ” Handles ephemeral filesystem  
βœ” Eliminates manual setup errors  
βœ” Improves reliability  

πŸ“ Project Structure

/config        β†’ Environment + feature configs  
/controllers   β†’ Request handling  
/services      β†’ Business logic  
/models        β†’ Database layer  
/middlewares   β†’ Auth, validation, RBAC  
/routes        β†’ API routes  
/utils         β†’ JWT, bcrypt, geo  
/db            β†’ DB connection  
/scripts       β†’ Admin seeding  
/error-lab     β†’ AppError + error middleware  

βš™οΈ Environment Configuration

Example:

JWT_SECRET=super-secret-key  
JWT_ACCESS_EXPIRES_IN=5m  
JWT_REFRESH_EXPIRES_IN=14d  
SESSION_EXPIRES_IN=1209600000  
COOKIE_HTTP_ONLY=true  

πŸ—„οΈ Database Design

Collections

Users

  • email (unique)
  • password (bcrypt hashed)
  • role

Sessions

  • sessionId
  • userId
  • device info
  • expiresAt

Refresh Tokens

  • refreshToken (unique)
  • sessionId (indexed)

⚑ Database Behavior Highlights

  • Token rotation deletes old entries
  • Session expiry checked per request
  • Logout removes session + tokens
  • .lean() used for optimized reads

πŸ” Protected Route Flow

  1. Validate Authorization header
  2. Verify access token
  3. Validate session from DB
  4. Extend session (sliding window)
  5. Attach req.user

🧠 Key Design Decisions

Why NOT JWT alone?

JWT alone:

❌ Cannot revoke ❌ Vulnerable to misuse

This system:

βœ” Adds session control βœ” Enables logout & invalidation βœ” Tracks active users


Why Token Rotation?

βœ” Prevents replay attacks βœ” Limits token lifetime even if stolen


Why Sliding Session?

βœ” Improves UX βœ” Keeps system secure & active


Why Service Layer?

βœ” Separation of concerns βœ” Reusable business logic βœ” Cleaner controllers


🌐 Deployment Design Decisions

Why not store Geo DB in repo?

❌ Large size (~60MB)  
❌ Not scalable  
❌ Not production-friendly  

Why runtime download?

βœ” Always available  
βœ” Works across environments  
βœ” No manual intervention  
βœ” Production-grade approach  

Why root route (/) added?

βœ” Handles Render health checks  
βœ” Prevents unnecessary 404 logs  
βœ” Improves observability  

πŸ§ͺ Testing Strategy

Tested using structured Postman collection:

  • Positive flows
  • Negative scenarios
  • Security edge cases
  • DB state verification (MongoDB Atlas)

🌍 Testing in Production

All APIs can be tested using:

BASE_URL = https://production-ready-backend-api-system.onrender.com

πŸ”Ή Recommended Flow

1. Register user  
2. Login  
3. Access protected routes  
4. Refresh token  
5. Test admin routes  

πŸ”Ή Verify via MongoDB Atlas

βœ” Users collection updates  
βœ” Sessions created  
βœ” Tokens rotated  
βœ” Roles updated  


πŸ”— API Reference (Production-Verified)

All routes are tested on production and follow consistent request/response patterns.

Base URL:

https://production-ready-backend-api-system.onrender.com

πŸ” Authentication Routes

1. Register

POST /auth/register

Body:

{
  "email": "user@example.com",
  "password": "your-password"
}

Response:

{
  "message": "User registered successfully",
  "user": {
    "_id": "...",
    "email": "...",
    "role": "user"
  }
}

2. Login

POST /auth/login

Body:

{
  "email": "user@example.com",
  "password": "your-password"
}

Response:

{
  "message": "Login successful",
  "accessToken": "...",
  "user": {
    "_id": "...",
    "email": "...",
    "role": "user"
  }
}

Behavior:

  • Sets refreshToken in httpOnly cookie
  • Creates session in DB
  • Captures device + IP + geo (if available)

3. Refresh Token

POST /auth/refresh

Headers:

Cookie: refreshToken=...

Response:

{
  "message": "Token refreshed",
  "accessToken": "..."
}

Behavior:

  • Rotates refresh token
  • Extends session (sliding session)
  • Invalidates old refresh token

4. Logout

POST /auth/logout

Response:

{
  "message": "user logged out."
}

Behavior:

  • Deletes session
  • Deletes refresh tokens
  • Clears cookie
  • Invalidates all authentication state

πŸ‘€ User Routes

5. Get Profile (Protected)

GET /profile

Headers:

Authorization: Bearer <accessToken>

Response:

{
  "message": "Profile fetched",
  "user": {...},
  "session": {...}
}

Behavior:

  • Requires valid access token
  • Verifies session from DB
  • Extends session expiry
  • Returns session metadata (device, IP, location)

πŸ‘₯ Admin Routes (RBAC)

⚠️ Admin credentials are not exposed publicly. Use your own seeded admin or create via controlled setup.


6. Get All Users (Admin Only)

GET /users

Headers:

Authorization: Bearer <adminToken>

Response:

{
  "message": "Users fetched successfully",
  "users": [...]
}

Behavior:

  • Only accessible by admin
  • Returns sanitized user data

7. Get User by ID (Owner / Admin)

GET /users/:id

Headers:

Authorization: Bearer <accessToken>

Behavior:

  • Owner β†’ allowed
  • Admin β†’ allowed
  • Others β†’ 403 Forbidden

8. Update User Role (Admin Only)

PUT /users/:id/<role>

Headers:

Authorization: Bearer <adminToken>
Content-Type: application/json

Body:

{
}

Behavior:

  • Only admin allowed
  • Updates role immediately in DB
  • Prevents invalid role values
  • Allowed roles : admin,user

9. Delete User (Owner / Admin)

DELETE /users/:id

Headers:

Authorization: Bearer <accessToken>

Behavior:

  • Owner β†’ can delete own account
  • Admin β†’ can delete any user
  • Other users β†’ 403 Forbidden

Response (Owner Self Delete):

{
  "message": "Your account deleted",
  "user": {
    "_id": "...",
    "email": "...",
    "role": "user"
  }
}

Response (Admin Delete):

{
  "message": "User deleted",
  "user": {
    "_id": "...",
    "email": "...",
    "role": "user"
  }
}

Internal Cleanup Performed:

1. Validate target user exists
2. Retrieve all sessions of that user
3. Extract all sessionIds
4. Delete refresh tokens linked to those sessionIds
5. Delete all sessions of that user
6. Delete the user document itself

Why this matters:

  • Prevents orphaned sessions
  • Prevents stale refresh token reuse
  • Ensures deleted users lose future access immediately
  • Maintains authentication consistency across the system

πŸ”„ CRUD Completeness

This project now implements full production-style CRUD behavior:

Create β†’ Register User  
Read β†’ Profile, Get Users, Get User by ID  
Update β†’ Update User Role  
Delete β†’ Delete User + Logout (session/token cleanup)

Unlike basic CRUD systems, delete operations here include:

βœ” Ownership validation  
βœ” RBAC enforcement  
βœ” Authentication cleanup  
βœ” Session invalidation  
βœ” Refresh token cleanup  

This makes DELETE a security-aware operation, not just database removal.


πŸ“Έ Additional Production Validation (Delete Flow)

The delete route was fully tested on the deployed production server.

Verified in Production:

βœ” User self-delete β†’ successful  
βœ” Admin delete another user β†’ successful  
βœ” Unauthorized delete attempt β†’ 403 Forbidden  
βœ” Invalid / already deleted user β†’ 404 Not Found  
βœ” Old access after deletion β†’ 401 Unauthorized  
βœ” Sessions removed from DB  
βœ” Refresh tokens removed from DB  

Validation Sources:

  • Postman (Production API)
  • MongoDB Atlas (users + sessions + refreshTokens verification)

This confirms full authentication cleanup and secure lifecycle handling.


⚠️ Error Handling Pattern

All errors follow consistent structure:

{
  "message": "Error message",
  "status": 400
}

πŸ”„ Complete Auth Lifecycle (Production Behavior)

Register β†’ Login β†’ Access Protected Routes  
↓  
Access Token Expires  
↓  
Refresh Token Used  
↓  
New Tokens Issued (Rotation)  
↓  
Logout β†’ Session + Tokens Destroyed

πŸ§ͺ Production Testing Coverage

The system has been tested for:

βœ” Positive flows (all routes)  
βœ” Negative cases (invalid token, missing token)  
βœ” RBAC enforcement  
βœ” Ownership validation  
βœ” Token rotation correctness  
βœ” Session lifecycle (create β†’ extend β†’ destroy)  
βœ” Database consistency (MongoDB Atlas)  
βœ” External dependency behavior (GeoDB)  

🧠 Behavioral Guarantees

βœ” Stateless JWT enhanced with stateful session validation  
βœ” Token misuse prevented via rotation  
βœ” Session acts as source of truth  
βœ” Authorization enforced at multiple levels (auth + role + ownership)  
βœ” System remains consistent across local and production environments  


πŸ“Έ Production Validation (Proof)

This system has been tested end-to-end on the deployed environment.

Verified in Production:

βœ” User registration β†’ reflected in MongoDB Atlas  
βœ” Login β†’ session + tokens created  
βœ” Refresh β†’ token rotation confirmed  
βœ” Logout β†’ session + tokens removed  
βœ” Profile β†’ session + device + geo data returned  
βœ” Admin routes β†’ RBAC enforced correctly  

Validation Sources:

  • Postman (production API testing)
  • MongoDB Atlas (real-time DB verification)

πŸ‘‰ This ensures the system is not just functional locally, but behaves correctly in real-world deployment.


πŸ“Š What Makes This Project Stand Out

This is NOT:

❌ Basic CRUD project ❌ Simple JWT implementation

This IS:

βœ” Hybrid authentication system βœ” Session-aware backend βœ” Security-focused design βœ” Production-style architecture βœ” Real-world token lifecycle management βœ” Cloud deployment + runtime dependency handling


🌍 Production-Ready Capabilities

βœ” Deployed on cloud (Render)  
βœ” Uses managed database (MongoDB Atlas)  
βœ” Handles environment-based configuration  
βœ” Supports runtime dependency setup  
βœ” Designed for real-world infrastructure  

πŸ§‘β€πŸ’» Tech Stack

  • Node.js
  • Express.js
  • MongoDB + Mongoose
  • JWT (jsonwebtoken)
  • bcryptjs
  • cookie-parser

🧰 Additional Production Tools

  • Axios (stream-based downloads)
  • tar (archive extraction)
  • MaxMind (Geo IP database)

🧠 Advanced Learnings Demonstrated

βœ” Difference between local vs production systems  
βœ” Handling ephemeral file systems  
βœ” Runtime dependency management  
βœ” Debugging deployment logs  
βœ” Managing external APIs securely  
βœ” Designing self-healing backend systems  

🧠 Key Learning Outcomes

This project demonstrates:

  • Deep understanding of authentication systems
  • Token lifecycle management
  • Backend security practices
  • Scalable architecture design
  • Clean code organization

πŸš€ Future Improvements

  • Rate limiting
  • CSRF protection
  • Refresh token hashing
  • Device/session management UI
  • Logging system (Winston)

πŸ”₯ Final Note

This project is not just about APIs β€” it’s about building a secure backend system with real-world constraints and behavior.


⭐ If you like this project

Give it a ⭐ and feel free to explore or suggest improvements!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors