Production-oriented, security-hardened authentication boilerplate for full-stack Node.js & React applications.
Key Features β’ Architecture β’ Getting Started β’ API Endpoints β’ Security β’ Testing
A complete, feature-rich authentication solution built on the MERN Stack (MongoDB, Express, React, Node.js). Designed out of the box with modern security best practices including short-lived Access Tokens, Refresh Token Rotation with database revocation, hashed OTP generation for email verification and password resets, IP-based rate limiting, and HTTP-only secure cookie delivery.
- π Dual-Token System: Short-lived Access Token (
15m) + Long-lived Refresh Token (7d). - π Refresh Token Rotation & Revocation: Automatic rotation on refresh with immediate revocation on logout or reuse detection.
- π‘οΈ Hashed OTP Storage: SHA-256 hashed OTPs stored in database with timing-safe comparison (
crypto.timingSafeEqual). - π Rate Limiting Protection:
express-rate-limitprotecting auth & OTP endpoints from brute-force attacks. - πͺ Secure Cookie Transport: Configured with
httpOnly,secure, andsameSiteflags to prevent XSS & CSRF credential theft. - π§ Redux Toolkit Integration: Global authentication state management with Redux Async Thunks.
- π¨ Modern UI Components: React 19 interface styled with Tailwind CSS and Lucide React icons.
- π‘οΈ Startup Environment Validation: Automatic schema verification of critical server environment variables.
- π§ͺ Zero-Config Testing: Automated integration test suite powered by Vitest &
mongodb-memory-server.
sequenceDiagram
autonumber
actor User
participant Frontend as React (Redux)
participant Backend as Express API
participant DB as MongoDB
User->>Frontend: Login Request (email, password)
Frontend->>Backend: POST /api/auth/login
Backend->>DB: Fetch user & verify password hash
Backend-->>Frontend: Set Access (15m) & Refresh Token (7d) in HTTP-only Cookies
Note over Frontend,Backend: Authenticated Requests Pass Access Token Cookie
Frontend->>Backend: GET /api/user/data (with Access Token)
Backend-->>Frontend: Return User Profile
Note over Frontend,Backend: On Access Token Expiry (15m)
Frontend->>Backend: POST /api/auth/refresh-token (with Refresh Token)
Backend->>DB: Verify & rotate Refresh Token in DB
Backend-->>Frontend: Issue new Access & Refresh Token pair
- Core: Node.js, Express.js
- Database: MongoDB & Mongoose ORM
- Security: JWT (
jsonwebtoken),bcryptjs, SHA-256 (crypto),helmet,express-rate-limit,cookie-parser - Email Dispatch:
nodemailer - Testing:
vitest,supertest,mongodb-memory-server
- Core: React 19, Vite
- State: Redux Toolkit (
@reduxjs/toolkit),react-redux - Routing & HTTP:
react-router-dom,axios(withwithCredentials: true) - Styling & UI: Tailwind CSS,
lucide-react,react-toastify
MERN-AUTH/
βββ backend/
β βββ Config/ # MongoDB, Mailer, & Env Validation logic
β βββ controller/ # Auth & User business logic
β βββ middleware/ # Auth & Rate limiter middlewares
β βββ model/ # Mongoose schemas
β βββ routes/ # API route definitions
β βββ tests/ # Integration test suite
β βββ .env.example # Safe backend env template
β βββ server.js # Entry point
βββ frontend/
β βββ src/
β β βββ components/ # Reusable UI components
β β βββ pages/ # Login, Register, Verify, Reset pages
β β βββ redux/ # Auth slices and Async Thunks
β βββ .env.example # Safe frontend env template
β βββ vite.config.js
βββ README.md
- Node.js:
v18.0.0or higher - npm:
v9.0.0or higher - MongoDB: Local instance or MongoDB Atlas
- SMTP Provider: SMTP credentials for sending verification emails (e.g., Brevo, SendGrid, Gmail)
# Clone the repository
git clone https://github.com/wahidulsami/MERN-AUTH.git
cd MERN-AUTH
# Set up environment files
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.envEdit backend/.env:
PORT=3000
NODE_ENV=development
MONGODB_URI=mongodb://localhost:27017/mern-auth
JWT_SECRET=your_super_secret_access_key
REFRESH_TOKEN_SECRET=your_super_secret_refresh_key
SENDER_EMAIL=noreply@yourdomain.com
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your_smtp_username
SMTP_PASS=your_smtp_passwordEdit frontend/.env:
VITE_BACKEND_URL=http://localhost:3000Start Backend:
cd backend
npm install
npm run devStart Frontend (in a new terminal):
cd frontend
npm install
npm run devVisit http://localhost:5173 in your browser.
| Method | Endpoint | Access | Description | Rate Limit |
|---|---|---|---|---|
POST |
/register |
Public | Register new user | 10 req / 15m |
POST |
/login |
Public | Authenticate user & issue cookie tokens | 10 req / 15m |
POST |
/logout |
Public | Revoke session & clear HTTP cookies | - |
POST |
/refresh-token |
Public | Rotate refresh token & issue new token pair | - |
GET |
/is-Auth |
Protected | Verify active authenticated session | - |
POST |
/send-verify-otp |
Protected | Send 6-digit email verification OTP | 5 req / 15m |
POST |
/verfiy-account |
Protected | Verify email using 6-digit OTP | - |
POST |
/send-reset-otp |
Public | Request password reset OTP via email | 5 req / 15m |
POST |
/reset-password |
Public | Reset password using verified OTP | - |
| Method | Endpoint | Access | Description |
|---|---|---|---|
GET |
/data |
Protected | Fetch profile details of logged-in user |
- Salted Password Hashing: Passwords hashed with
bcryptjs(cost factor 10). - Hashed OTP Storage: Raw 6-digit OTPs are never stored in DB; only SHA-256 hashes are saved.
- Timing-Attack Resistance: OTP matching performed using
crypto.timingSafeEqual. - XSS & CSRF Mitigations: Session tokens are passed exclusively in
httpOnlysecure cookies with strictsameSitepolicies. - IP Rate Limiting: Endpoint-specific limits using
express-rate-limitto prevent brute-force attacks. - Startup Protection: Application validates all required env variables before starting up.
The backend includes automated integration tests using Vitest and In-Memory MongoDB:
cd backend
npm testDistributed under the MIT License. See LICENSE for more information.