This is a basic JWT (JSON Web Token) authentication system built with React + TypeScript frontend and Node.js + Express backend. The project demonstrates fundamental JWT concepts including access tokens, refresh tokens, and protected routes.
- In-memory storage: User data and refresh tokens are stored in memory (fakedb.js) - data is lost on server restart
- Weak secrets: JWT secrets are hardcoded and not properly secured
- No rate limiting: No protection against brute force attacks
- No input validation: Limited validation on user inputs
- No HTTPS: No SSL/TLS encryption
- No password complexity requirements: Basic password validation only
- No session management: No proper session handling
- No audit logging: No security event logging
- No CSRF protection: No Cross-Site Request Forgery protection
- No XSS protection: Limited XSS protection measures
- Learning JWT token flow
- Understanding authentication concepts
- Practicing React + Node.js development
- Studying token-based authentication patterns
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ React Frontend│ │ Express Server │ │ In-Memory DB │
│ (Port 5173) │◄──►│ (Port 4000) │◄──►│ (fakedb.js) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
- Form Handling: Login and registration forms with validation
- Protected Routes: Route protection based on authentication status
- Token Management: Automatic token refresh and storage
- Error Handling: User-friendly error messages and loading states
- Responsive Design: Mobile-friendly interface
- JWT Authentication: Access tokens (15min) and refresh tokens (7 days)
- Password Hashing: bcryptjs for secure password storage
- CORS Configuration: Cross-origin resource sharing setup
- Cookie Management: HTTP-only cookies for refresh tokens
- Protected Endpoints: Route protection middleware
- Token Refresh: Automatic token renewal system
JWT-intro/
├── front-end/ # React + TypeScript frontend
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── Login.tsx # Login form
│ │ │ ├── Register.tsx # Registration form
│ │ │ ├── Content.tsx # Dashboard content
│ │ │ ├── Protected.tsx # Protected route demo
│ │ │ └── Navigation.tsx # Navigation component
│ │ ├── Context/ # React context for state management
│ │ ├── App.tsx # Main app component
│ │ ├── main.tsx # App entry point
│ │ └── index.css # Global styles
│ └── package.json
├── server/ # Node.js + Express backend
│ ├── src/
│ │ ├── index.js # Main server file
│ │ ├── tokens.js # JWT token utilities
│ │ ├── isAuth.js # Authentication middleware
│ │ └── fakedb.js # In-memory database
│ ├── start.js # Server startup script
│ └── package.json
└── README.md
- Node.js (v14 or higher)
- npm or yarn
cd server
npm install
npm start
The server will start on http://localhost:4000
cd front-end
npm install
npm run dev
The frontend will start on http://localhost:5173
User submits registration form
↓
Server hashes password with bcrypt
↓
User stored in memory (fakedb.js)
↓
Redirect to login page
User submits login credentials
↓
Server validates credentials
↓
Generate access token (15min) + refresh token (7 days)
↓
Access token sent in response body
↓
Refresh token stored as HTTP-only cookie
↓
Redirect to dashboard
Frontend sends access token in Authorization header
↓
Server validates token using isAuth middleware
↓
If valid: return protected content
↓
If invalid: return 401 error
Access token expires (15min)
↓
Frontend automatically calls /refresh_token
↓
Server validates refresh token from cookie
↓
Generate new access token + refresh token
↓
Update user's refresh token in memory
↓
Send new access token to frontend
User clicks logout
↓
Clear refresh token cookie
↓
Clear frontend state
↓
Redirect to login page
This project demonstrates:
- JWT Token Structure: Understanding access vs refresh tokens
- Token Lifecycle: Creation, validation, refresh, and expiration
- HTTP-only Cookies: Secure storage of refresh tokens
- Bearer Token Authentication: Authorization header usage
- CORS Configuration: Cross-origin request handling
- Password Security: Hashing with bcrypt
- Protected Routes: Frontend and backend route protection
- State Management: React context for authentication state
- Error Handling: Proper error responses and user feedback
Method | Endpoint | Description |
---|---|---|
POST | /register |
User registration |
POST | /login |
User authentication |
POST | /logout |
User logout |
POST | /protected |
Protected route demo |
POST | /refresh_token |
Token refresh |
If you were to use this in production (which you shouldn't), you would need to add:
- Database: Replace in-memory storage with PostgreSQL/MongoDB
- Environment Variables: Proper secret management
- HTTPS: SSL/TLS encryption
- Rate Limiting: Protection against brute force attacks
- Input Validation: Comprehensive input sanitization
- Password Policies: Strong password requirements
- Session Management: Proper session handling
- Audit Logging: Security event tracking
- CSRF Protection: Cross-Site Request Forgery prevention
- XSS Protection: Cross-Site Scripting prevention
- Security Headers: Additional HTTP security headers
- Error Handling: Proper error logging and monitoring