Skip to content

Commit b0500de

Browse files
committed
feat(examples): add Express.js HTTP server with JWT middleware 🔐
1 parent def687e commit b0500de

File tree

4 files changed

+1094
-9
lines changed

4 files changed

+1094
-9
lines changed

examples/http-server/README.md

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,31 @@ This directory contains HTTP server examples demonstrating how to use Secure-JWT
44

55
## 📚 Examples
66

7-
### 🚀 Simple Server (`simple-server.ts`)
7+
### 🚀 Express Server (`express-server.ts`)
88

9-
A complete HTTP server implementation using only Node.js built-in modules - no external dependencies!
9+
A modern Express.js server with JWT middleware - perfect for quick prototyping and learning!
1010

1111
**Features:**
12+
- **Express.js framework** - Modern, fast web framework
13+
- **JWT middleware** - Reusable authentication middleware
14+
- **Protected/unprotected routes** - Clear separation of access levels
15+
- **Login endpoint** - Generate JWT tokens
16+
- **Health check** - Server status monitoring
17+
- **TypeScript support** - Full type safety
18+
- **Error handling** - Comprehensive error responses
19+
20+
**Endpoints:**
21+
- `GET /public` - Public route (no authentication)
22+
- `GET /protected` - Protected route (requires JWT)
23+
- `POST /login` - Login to get JWT token
24+
- `GET /health` - Health check
25+
26+
### 🔧 Simple Server (`simple-server.ts`)
27+
28+
A complete HTTP server implementation using only Node.js built-in modules - zero dependencies!
29+
30+
**Features:**
31+
- **Zero dependencies** - Pure Node.js implementation
1232
- **Login endpoint** - Authenticate users and issue JWT tokens
1333
- **Protected endpoints** - Verify JWT tokens for access control
1434
- **Role-based access** - Admin-only endpoints
@@ -29,7 +49,29 @@ A complete HTTP server implementation using only Node.js built-in modules - no e
2949

3050
## 🚀 Quick Start
3151

32-
1. **Start the server:**
52+
### Express Server
53+
1. **Start the Express server:**
54+
```bash
55+
npx tsx examples/http-server/express-server.ts
56+
```
57+
58+
2. **Test the endpoints:**
59+
```bash
60+
# Test public route
61+
curl http://localhost:3000/public
62+
63+
# Login to get token
64+
curl -X POST http://localhost:3000/login \
65+
-H "Content-Type: application/json" \
66+
-d '{"username":"admin","password":"password"}'
67+
68+
# Use the token from login response
69+
curl -H "Authorization: Bearer <your-token>" \
70+
http://localhost:3000/protected
71+
```
72+
73+
### Simple Server
74+
1. **Start the Simple server:**
3375
```bash
3476
npx tsx examples/http-server/simple-server.ts
3577
```
@@ -48,6 +90,12 @@ A complete HTTP server implementation using only Node.js built-in modules - no e
4890

4991
## 👥 Test Users
5092

93+
### Express Server
94+
| Username | Password | Role |
95+
|----------|----------|-------|
96+
| admin | password | admin |
97+
98+
### Simple Server
5199
| Username | Password | Role |
52100
|----------|----------|-------|
53101
| admin | admin123 | admin |
@@ -112,13 +160,27 @@ A complete HTTP server implementation using only Node.js built-in modules - no e
112160
}
113161
```
114162

115-
## 💡 Why This Example?
163+
## 💡 Why These Examples?
116164

117-
This example demonstrates:
118-
- **Real-world usage** - How JWT authentication works in practice
165+
### Express Server
166+
Perfect for:
167+
- **Quick prototyping** - Fast development with Express.js
168+
- **Learning JWT basics** - Simple, clean implementation
169+
- **Modern web apps** - TypeScript + Express.js stack
170+
- **Middleware patterns** - Reusable authentication middleware
171+
172+
### Simple Server
173+
Perfect for:
119174
- **Zero dependencies** - Pure Node.js implementation
175+
- **Production applications** - Complete, robust server
176+
- **Role-based access** - Admin vs user permissions
177+
- **Full-featured auth** - Token verification, CORS, health checks
178+
- **Learning internals** - Understand HTTP server mechanics
179+
180+
Both examples demonstrate:
181+
- **Real-world usage** - How JWT authentication works in practice
120182
- **Security best practices** - Proper token handling and validation
121183
- **Production patterns** - Error handling, CORS, health checks
122-
- **Role-based access** - Different permission levels
184+
- **TypeScript support** - Full type safety and IntelliSense
123185

124186
Perfect for understanding how to integrate Secure-JWT into your applications! 🚀
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import express, { type Request, type Response, type NextFunction } from 'express'
2+
import SecureJWT from '../../src/index'
3+
4+
/**
5+
* Express application instance
6+
*/
7+
const app = express()
8+
9+
/**
10+
* Server port number
11+
*/
12+
const PORT = process.env.PORT || 3000
13+
14+
/**
15+
* JWT instance with encryption settings
16+
*/
17+
const jwt = new SecureJWT({
18+
secret: process.env.JWT_SECRET || 'your-super-secret-key-change-in-production',
19+
expireIn: '1h',
20+
version: '1.0.0',
21+
algorithm: 'aes-256-gcm'
22+
})
23+
24+
/**
25+
* Parse JSON request bodies
26+
*/
27+
app.use(express.json())
28+
29+
/**
30+
* Check if request has valid JWT token
31+
* @param req - Request object
32+
* @param res - Response object
33+
* @param next - Next function
34+
*/
35+
const authenticateToken = (req: Request, res: Response, next: NextFunction) => {
36+
const authHeader = req.headers['authorization']
37+
const token = authHeader && authHeader.split(' ')[1]
38+
if (!token) {
39+
return res.status(401).json({
40+
error: 'Access token required',
41+
message: 'Please provide a valid JWT token in Authorization header'
42+
})
43+
}
44+
try {
45+
const isValid = jwt.verify(token)
46+
if (!isValid) {
47+
return res.status(403).json({
48+
error: 'Invalid token',
49+
message: 'Token is invalid or expired'
50+
})
51+
}
52+
const userData = jwt.decode(token)
53+
req.user = userData
54+
next()
55+
} catch (error) {
56+
return res.status(403).json({
57+
error: 'Token verification failed',
58+
message: error instanceof Error ? error.message : 'Unknown error'
59+
})
60+
}
61+
}
62+
63+
/**
64+
* Add user property to Express Request interface
65+
*/
66+
declare global {
67+
namespace Express {
68+
interface Request {
69+
user?: any
70+
}
71+
}
72+
}
73+
74+
/**
75+
* Public route handler
76+
* @param req - Request object
77+
* @param res - Response object
78+
*/
79+
app.get('/public', (req: Request, res: Response) => {
80+
res.json({
81+
message: 'This is a public route - no authentication required',
82+
timestamp: new Date().toISOString(),
83+
data: {
84+
server: 'Secure-JWT Express Server',
85+
version: '1.0.0',
86+
status: 'running'
87+
}
88+
})
89+
})
90+
91+
/**
92+
* Protected route handler
93+
* @param req - Request object with user data
94+
* @param res - Response object
95+
*/
96+
app.get('/protected', authenticateToken, (req: Request, res: Response) => {
97+
res.json({
98+
message: 'Welcome to protected route!',
99+
user: req.user,
100+
timestamp: new Date().toISOString(),
101+
data: {
102+
server: 'Secure-JWT Express Server',
103+
version: '1.0.0',
104+
status: 'authenticated'
105+
}
106+
})
107+
})
108+
109+
/**
110+
* Login route handler
111+
* @param req - Request object with login data
112+
* @param res - Response object
113+
*/
114+
app.post('/login', (req: Request, res: Response) => {
115+
const { username, password } = req.body
116+
if (!username || !password) {
117+
return res.status(400).json({
118+
error: 'Missing credentials',
119+
message: 'Username and password are required'
120+
})
121+
}
122+
if (username === 'admin' && password === 'password') {
123+
const userData = {
124+
id: 1,
125+
username: 'admin',
126+
role: 'admin',
127+
permissions: ['read', 'write', 'admin'],
128+
loginTime: new Date().toISOString()
129+
}
130+
try {
131+
const token = jwt.sign(userData)
132+
res.json({
133+
message: 'Login successful',
134+
token,
135+
user: userData,
136+
expiresIn: '1 hour'
137+
})
138+
} catch (error) {
139+
res.status(500).json({
140+
error: 'Token generation failed',
141+
message: error instanceof Error ? error.message : 'Unknown error'
142+
})
143+
}
144+
} else {
145+
res.status(401).json({
146+
error: 'Invalid credentials',
147+
message: 'Username or password is incorrect'
148+
})
149+
}
150+
})
151+
152+
/**
153+
* Health check route handler
154+
* @param req - Request object
155+
* @param res - Response object
156+
*/
157+
app.get('/health', (req: Request, res: Response) => {
158+
res.json({
159+
status: 'healthy',
160+
timestamp: new Date().toISOString(),
161+
uptime: process.uptime(),
162+
memory: process.memoryUsage()
163+
})
164+
})
165+
166+
/**
167+
* Handle server errors
168+
* @param err - Error object
169+
* @param req - Request object
170+
* @param res - Response object
171+
* @param next - Next function
172+
*/
173+
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
174+
console.error('Error:', err)
175+
res.status(500).json({
176+
error: 'Internal server error',
177+
message: 'Something went wrong'
178+
})
179+
})
180+
181+
/**
182+
* Handle 404 errors
183+
* @param req - Request object
184+
* @param res - Response object
185+
*/
186+
app.use((req: Request, res: Response) => {
187+
res.status(404).json({
188+
error: 'Route not found',
189+
message: `Cannot ${req.method} ${req.originalUrl}`
190+
})
191+
})
192+
193+
/**
194+
* Start the server
195+
*/
196+
app.listen(PORT, () => {
197+
console.log(`🚀 Secure-JWT Express Server running on port ${PORT}`)
198+
console.log(`📝 Available routes:`)
199+
console.log(` GET /public - Public route (no auth)`)
200+
console.log(` GET /protected - Protected route (requires auth)`)
201+
console.log(` POST /login - Login to get JWT token`)
202+
console.log(` GET /health - Health check`)
203+
console.log(`\n🔐 Test with:`)
204+
console.log(` curl http://localhost:${PORT}/public`)
205+
console.log(` curl -X POST http://localhost:${PORT}/login -H "Content-Type: application/json" -d '{"username":"admin","password":"password"}'`)
206+
console.log(` curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:${PORT}/protected`)
207+
})

0 commit comments

Comments
 (0)