Comprehensive guide to authentication, authorization, and security features in the Qwe Framework.
- Overview
- JWT Authentication
- Middleware System
- Authorization Patterns
- Security Best Practices
- Production Considerations
- Examples & Use Cases
Qwe Framework provides a complete authentication and authorization system built on JWT (JSON Web Tokens) with zero external dependencies. The system includes token generation, validation, middleware for route protection, and flexible authorization patterns.
- 🔐 JWT Implementation: Complete JWT library with HS256/384/512 support
- 🛡️ Middleware System: Easy route protection with configurable options
- 👥 Role-Based Access: Built-in role and permission-based authorization
- 🔑 Flexible Token Extraction: Multiple token sources (headers, query, cookies)
- ⚡ High Performance: Zero dependencies, optimized for speed
- 🔒 Security First: Built-in protections against common vulnerabilities
The framework provides a complete JWT implementation accessible through the context object:
// Using JWT through context
app.post('/auth/login', async (qwe) => {
const { email, password } = qwe.body;
// Authenticate user (implement your logic)
const user = await authenticateUser(email, password);
if (!user) {
return qwe.unauthorized('Invalid credentials');
}
// Generate JWT token
const token = qwe.jwt.sign(
{
userId: user.id,
email: user.email,
role: user.role,
permissions: user.permissions
},
process.env.JWT_SECRET!,
{
expiresIn: '24h',
issuer: 'my-app',
audience: 'my-api'
}
);
return qwe.success('Login successful', {
token,
user: { id: user.id, email: user.email, role: user.role }
});
});import { createJWT } from 'qwe-framework';
const jwt = createJWT();
// Sign a token
const token = jwt.sign(
{ userId: 123, role: 'admin' },
'your-secret-key',
{
expiresIn: '1h',
issuer: 'my-app',
audience: 'my-api',
subject: 'user-auth'
}
);
// Verify a token
try {
const payload = jwt.verify(token, 'your-secret-key');
console.log('User:', payload.userId, 'Role:', payload.role);
} catch (error) {
console.error('Token verification failed:', error.message);
}
// Decode token without verification (for debugging)
const decoded = jwt.decode(token);
console.log('Token payload:', decoded);For enhanced security, use access/refresh token pairs:
// Create token pair
const { accessToken, refreshToken } = jwt.createTokenPair(
{ userId: 123, role: 'user' },
'your-secret-key',
{
accessTokenExpiry: '15m', // Short-lived access token
refreshTokenExpiry: '7d' // Long-lived refresh token
}
);
// Refresh access token
app.post('/auth/refresh', async (qwe) => {
const { refreshToken } = qwe.body;
try {
const newAccessToken = jwt.refreshAccessToken(
refreshToken,
process.env.JWT_SECRET!,
{ userId: user.id, role: user.role },
'15m'
);
return qwe.success('Token refreshed', { accessToken: newAccessToken });
} catch (error) {
return qwe.unauthorized('Invalid refresh token');
}
});Protect routes with JWT authentication middleware:
import { jwtMiddleware } from 'qwe-framework';
// Global JWT protection
app.use(jwtMiddleware({
secret: process.env.JWT_SECRET!,
algorithms: ['HS256'],
issuer: 'my-app',
audience: 'my-api'
}));
// Route-specific protection
app.get('/api/profile',
jwtMiddleware({ secret: process.env.JWT_SECRET! }),
(qwe) => {
// User data available in qwe.user
return qwe.success('Profile data', { user: qwe.user });
}
);Configure how tokens are extracted from requests:
app.use(jwtMiddleware({
secret: process.env.JWT_SECRET!,
getToken: (qwe) => {
// Try multiple sources
return qwe.headers['x-auth-token'] || // Custom header
qwe.query['access_token'] || // Query parameter
qwe.cookies['jwt'] || // Cookie
qwe.headers['authorization']?.replace('Bearer ', ''); // Authorization header
}
}));Some routes may benefit from user context but don't require authentication:
import { optionalAuth } from 'qwe-framework';
app.get('/api/posts',
optionalAuth({ secret: process.env.JWT_SECRET! }),
(qwe) => {
const posts = getPosts();
// Enhance response if user is authenticated
if (qwe.user) {
posts.forEach(post => {
post.isLiked = isPostLikedByUser(post.id, qwe.user.userId);
});
}
return qwe.success('Posts retrieved', posts);
}
);Customize authentication error responses:
app.use(jwtMiddleware({
secret: process.env.JWT_SECRET!,
onError: (qwe, error) => {
console.error('Authentication error:', error.message);
// Log security events
logSecurityEvent({
type: 'auth_failure',
ip: qwe.ip,
userAgent: qwe.headers['user-agent'],
error: error.message
});
}
}));Protect routes based on user roles:
import { requireRoles } from 'qwe-framework';
// Single role requirement
app.get('/admin/users',
jwtMiddleware({ secret: process.env.JWT_SECRET! }),
requireRoles('admin'),
(qwe) => {
return qwe.success('Admin users', getAdminUsers());
}
);
// Multiple role options
app.get('/admin/dashboard',
jwtMiddleware({ secret: process.env.JWT_SECRET! }),
requireRoles('admin', 'moderator', 'supervisor'),
(qwe) => {
return qwe.success('Dashboard data', getDashboardData());
}
);Fine-grained permissions for specific actions:
import { requirePermissions } from 'qwe-framework';
// Single permission
app.post('/api/posts',
jwtMiddleware({ secret: process.env.JWT_SECRET! }),
requirePermissions('posts:create'),
(qwe) => {
const post = createPost(qwe.body, qwe.user.userId);
return qwe.created('Post created', post);
}
);
// Multiple permissions (all required)
app.delete('/api/posts/:id',
jwtMiddleware({ secret: process.env.JWT_SECRET! }),
requirePermissions('posts:delete', 'posts:moderate'),
(qwe) => {
deletePost(qwe.params.id);
return qwe.success('Post deleted');
}
);Protect resources based on ownership:
import { requireOwnershipOrRole } from 'qwe-framework';
// Only owner or admin can access
app.get('/api/users/:id/profile',
jwtMiddleware({ secret: process.env.JWT_SECRET! }),
requireOwnershipOrRole(
(qwe) => qwe.params.id, // Get resource owner ID
['admin', 'moderator'] // Admin roles that can access any resource
),
(qwe) => {
const profile = getUserProfile(qwe.params.id);
return qwe.success('Profile retrieved', profile);
}
);
// Custom ownership logic
app.put('/api/posts/:id',
jwtMiddleware({ secret: process.env.JWT_SECRET! }),
requireOwnershipOrRole(
async (qwe) => {
// Get post owner from database
const post = await getPost(qwe.params.id);
return post.authorId;
},
['admin', 'moderator']
),
(qwe) => {
const updatedPost = updatePost(qwe.params.id, qwe.body);
return qwe.success('Post updated', updatedPost);
}
);Apply different rules based on context:
// Custom authorization middleware
const requireOwnerOrPublic = async (qwe: QweContext, next: () => Promise<void>) => {
const resource = await getResource(qwe.params.id);
// Public resources don't need ownership check
if (resource.isPublic) {
await next();
return;
}
// Private resources need authentication
if (!qwe.user) {
return qwe.unauthorized('Authentication required for private resources');
}
// Check ownership or admin role
if (resource.ownerId !== qwe.user.userId && !qwe.user.roles?.includes('admin')) {
return qwe.forbidden('Access denied');
}
await next();
};
app.get('/api/resources/:id',
optionalAuth({ secret: process.env.JWT_SECRET! }),
requireOwnerOrPublic,
(qwe) => {
const resource = getResource(qwe.params.id);
return qwe.success('Resource retrieved', resource);
}
);// 1. Use strong secrets
const jwtSecret = process.env.JWT_SECRET || generateStrongSecret();
// 2. Short-lived access tokens
const accessToken = jwt.sign(payload, jwtSecret, { expiresIn: '15m' });
// 3. Secure token storage
app.post('/auth/login', (qwe) => {
const token = generateToken(user);
// Set secure cookie
qwe.cookie('jwt', token, {
httpOnly: true, // Prevent XSS
secure: true, // HTTPS only
sameSite: 'strict', // CSRF protection
maxAge: 15 * 60 * 1000 // 15 minutes
});
return qwe.success('Login successful', { user });
});Implement token blacklisting for enhanced security:
// Token revocation store
const revokedTokens = new Set<string>();
// Revoke token
app.post('/auth/logout',
jwtMiddleware({ secret: process.env.JWT_SECRET! }),
(qwe) => {
const token = extractTokenFromRequest(qwe);
revokedTokens.add(token);
// Clear cookie
qwe.cookie('jwt', '', { maxAge: 0 });
return qwe.success('Logged out successfully');
}
);
// Check revocation in middleware
app.use(jwtMiddleware({
secret: process.env.JWT_SECRET!,
isRevoked: (qwe, payload) => {
const token = extractTokenFromRequest(qwe);
return revokedTokens.has(token);
}
}));Protect authentication endpoints from brute force attacks:
import { rateLimiter } from 'qwe-framework';
// Strict rate limiting for login attempts
app.use('/auth/login', rateLimiter({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // 5 attempts per window
message: 'Too many login attempts, please try again later',
keyGenerator: (qwe) => qwe.ip // Rate limit per IP
}));
// Different limits for password reset
app.use('/auth/reset-password', rateLimiter({
windowMs: 60 * 60 * 1000, // 1 hour
max: 3, // 3 attempts per hour
keyGenerator: (qwe) => qwe.body.email || qwe.ip
}));Always validate authentication-related inputs:
const loginSchema = qwe.validate.object({
email: qwe.validate.string().email().required(),
password: qwe.validate.string().min(8).required()
});
app.post('/auth/login', async (qwe) => {
// Validate input
const validation = await qwe.validate(loginSchema, qwe.body);
if (!validation.success) {
return qwe.badRequest('Invalid input', validation.errors);
}
const { email, password } = validation.data;
// Authenticate user
const user = await authenticateUser(email, password);
if (!user) {
return qwe.unauthorized('Invalid credentials');
}
// Continue with token generation...
});// Environment-specific JWT configuration
const jwtConfig = {
secret: process.env.JWT_SECRET!,
accessTokenExpiry: process.env.NODE_ENV === 'production' ? '15m' : '1h',
refreshTokenExpiry: process.env.NODE_ENV === 'production' ? '7d' : '30d',
algorithms: ['HS256'] as const,
issuer: process.env.JWT_ISSUER || 'qwe-app',
audience: process.env.JWT_AUDIENCE || 'qwe-api'
};Track authentication events for security monitoring:
const authLogger = {
loginSuccess: (userId: string, ip: string) => {
console.log(`[AUTH] Login success: User ${userId} from ${ip}`);
},
loginFailure: (email: string, ip: string, reason: string) => {
console.warn(`[AUTH] Login failed: ${email} from ${ip} - ${reason}`);
},
tokenExpired: (userId: string, ip: string) => {
console.log(`[AUTH] Token expired: User ${userId} from ${ip}`);
},
suspiciousActivity: (details: any) => {
console.error(`[SECURITY] Suspicious activity detected:`, details);
}
};
// Use in middleware
app.use(jwtMiddleware({
secret: process.env.JWT_SECRET!,
onError: (qwe, error) => {
if (error.message.includes('expired')) {
authLogger.tokenExpired(qwe.user?.userId || 'unknown', qwe.ip);
} else {
authLogger.suspiciousActivity({
ip: qwe.ip,
userAgent: qwe.headers['user-agent'],
error: error.message,
url: qwe.url
});
}
}
}));Monitor authentication system health:
app.get('/health/auth', (qwe) => {
const healthCheck = {
timestamp: new Date().toISOString(),
status: 'healthy',
checks: {
jwtSecret: !!process.env.JWT_SECRET,
tokenGeneration: false,
tokenVerification: false
}
};
try {
// Test token generation
const testToken = qwe.jwt.sign({ test: true }, process.env.JWT_SECRET!, { expiresIn: '1s' });
healthCheck.checks.tokenGeneration = true;
// Test token verification
qwe.jwt.verify(testToken, process.env.JWT_SECRET!);
healthCheck.checks.tokenVerification = true;
} catch (error) {
healthCheck.status = 'unhealthy';
}
return qwe.success('Auth health check', healthCheck);
});import { createApp, jwtMiddleware, requireRoles, rateLimiter } from 'qwe-framework';
const app = createApp();
// Rate limiting for auth endpoints
app.use('/auth', rateLimiter({ windowMs: 15 * 60 * 1000, max: 10 }));
// User registration
app.post('/auth/register', async (qwe) => {
const validation = await qwe.validate(registerSchema, qwe.body);
if (!validation.success) {
return qwe.badRequest('Validation failed', validation.errors);
}
const { email, password, name } = validation.data;
// Check if user exists
const existingUser = await findUserByEmail(email);
if (existingUser) {
return qwe.conflict('User already exists');
}
// Hash password and create user
const hashedPassword = await qwe.hash.hash(password);
const user = await createUser({
email,
password: hashedPassword,
name,
role: 'user'
});
// Generate tokens
const accessToken = qwe.jwt.sign(
{ userId: user.id, email: user.email, role: user.role },
process.env.JWT_SECRET!,
{ expiresIn: '15m' }
);
const refreshToken = qwe.jwt.sign(
{ userId: user.id, type: 'refresh' },
process.env.JWT_SECRET!,
{ expiresIn: '7d' }
);
return qwe.created('User registered successfully', {
user: { id: user.id, email: user.email, name: user.name },
accessToken,
refreshToken
});
});
// User login
app.post('/auth/login', async (qwe) => {
const { email, password } = qwe.body;
const user = await findUserByEmail(email);
if (!user || !await qwe.hash.verify(password, user.password)) {
return qwe.unauthorized('Invalid credentials');
}
// Update last login
await updateUserLastLogin(user.id);
// Generate tokens
const accessToken = qwe.jwt.sign(
{ userId: user.id, email: user.email, role: user.role },
process.env.JWT_SECRET!,
{ expiresIn: '15m' }
);
return qwe.success('Login successful', {
user: { id: user.id, email: user.email, name: user.name },
accessToken
});
});
// Protected user profile
app.get('/api/profile',
jwtMiddleware({ secret: process.env.JWT_SECRET! }),
(qwe) => {
const profile = getUserProfile(qwe.user.userId);
return qwe.success('Profile retrieved', profile);
}
);
// Admin-only endpoint
app.get('/api/admin/users',
jwtMiddleware({ secret: process.env.JWT_SECRET! }),
requireRoles('admin'),
(qwe) => {
const users = getAllUsers();
return qwe.success('Users retrieved', users);
}
);Share authentication across services:
// Shared JWT middleware for microservices
const sharedAuthMiddleware = jwtMiddleware({
secret: process.env.SHARED_JWT_SECRET!,
issuer: 'auth-service',
audience: ['user-service', 'order-service', 'payment-service'],
algorithms: ['HS256']
});
// User service
app.use('/api/users', sharedAuthMiddleware);
app.get('/api/users/:id', (qwe) => {
const user = getUser(qwe.params.id);
return qwe.success('User found', user);
});
// Order service
app.use('/api/orders', sharedAuthMiddleware);
app.post('/api/orders', requireRoles('customer'), (qwe) => {
const order = createOrder(qwe.body, qwe.user.userId);
return qwe.created('Order created', order);
});The Qwe Framework authentication system provides enterprise-grade security with zero dependencies. The combination of JWT tokens, flexible middleware, and authorization patterns covers all common authentication scenarios while maintaining high performance and developer productivity.
- Zero Dependencies: Complete JWT implementation built-in
- Flexible Authorization: Role, permission, and ownership-based access
- Security First: Built-in protections and best practices
- High Performance: Optimized for speed and efficiency
- Developer Friendly: Clean APIs and comprehensive error handling
- ⚡ Explore Real-time Features for WebSocket authentication
- 🗄️ Set up Database & ORM for user management
- 📊 Learn Performance monitoring for auth metrics
- 🚀 Read Deployment for production security
Need help? Check the API Reference for complete JWT and middleware documentation.