auth-cache
v1.0.1
Published
A lightweight JWT session cache that reduces database calls with LRU + TTL, revocation hooks, and middleware integration
Downloads
9
Maintainers
Readme
AuthCache
A high-performance JWT session cache that significantly reduces database load by intelligently caching verified user sessions. Built with TypeScript and designed for production environments, AuthCache combines LRU (Least Recently Used) and TTL (Time To Live) eviction strategies with comprehensive middleware support.
Features
- JWT Verification: Industry-standard token verification with support for RS256 and EdDSA algorithms
- Intelligent Caching: LRU + TTL hybrid cache with configurable memory limits and automatic cleanup
- Session Management: Built-in user session invalidation and revocation capabilities
- Middleware Integration: Drop-in middleware for Express, Fastify, and other Node.js frameworks
- Performance Monitoring: Real-time metrics tracking for cache hits, misses, and evictions
- Type Safety: Full TypeScript support with comprehensive type definitions
- Production Ready: Robust error handling, logging, and configuration management
- Database Fallback: Seamless integration with existing user authentication systems
Installation
npm install auth-cacheyarn add auth-cachepnpm add auth-cacheQuick Start
Basic Setup
import { AuthCache } from 'auth-cache';
const authCache = new AuthCache({
maxUsers: 1000,
idleTimeout: 20 * 60 * 1000, // 20 minutes
jwtSecret: process.env.JWT_SECRET,
jwtAlgorithms: ['RS256', 'EdDSA'],
dbFallback: async (userId) => {
return await database.findUserById(userId);
},
logger: (message, level) => {
console.log(`[${level}] ${message}`);
}
});Express Integration
import express from 'express';
import { AuthCache, AuthenticatedRequest } from 'auth-cache';
const app = express();
const authCache = new AuthCache({ /* config */ });
// Apply middleware globally
app.use(authCache.middleware());
// Public route (authentication optional)
app.get('/health', (req: AuthenticatedRequest, res) => {
res.json({
status: 'ok',
authenticated: !!req.user
});
});
// Protected route (authentication required)
app.use('/api/protected', authCache.middlewareWithOptions({
required: true,
unauthorizedMessage: 'Authentication required',
unauthorizedStatusCode: 401
}));
app.get('/api/protected/profile', (req: AuthenticatedRequest, res) => {
res.json({
user: req.user,
cacheInfo: req.authCache
});
});Manual Usage
// Direct user verification
const user = await authCache.checkUser(jwtToken);
if (user) {
console.log('User authenticated:', user.id);
}
// Cache management
authCache.storeUser('user123', userData, jwtExpiration);
authCache.purgeByUserId('user123');
authCache.cleanup(); // Manual cleanup of expired entries
// Metrics monitoring
const metrics = authCache.getMetrics();
console.log(`Cache hit rate: ${metrics.cacheHits / (metrics.cacheHits + metrics.cacheMisses) * 100}%`);Configuration
The AuthCache constructor accepts a configuration object with the following options:
interface AuthCacheConfig {
maxUsers?: number; // Maximum users in cache (default: 1000)
idleTimeout?: number; // Time in ms before idle eviction (default: 1200000 - 20 min)
dbFallback?: (userId: string) => Promise<User | null>; // Database lookup function
jwtSecret?: string; // JWT verification secret/key
jwtAlgorithms?: string[]; // Supported algorithms (default: ['RS256', 'EdDSA'])
sanitizeUser?: (user: User) => User; // User data sanitization function
logger?: (message: string, level: 'info' | 'warn' | 'error') => void; // Logging function
}Configuration Examples
Development Setup
const authCache = new AuthCache({
maxUsers: 100,
idleTimeout: 5 * 60 * 1000, // 5 minutes for development
jwtSecret: 'your-dev-secret',
logger: console.log
});Production Setup
const authCache = new AuthCache({
maxUsers: 10000,
idleTimeout: 30 * 60 * 1000, // 30 minutes
jwtSecret: process.env.JWT_PUBLIC_KEY,
jwtAlgorithms: ['RS256'],
dbFallback: async (userId) => {
const user = await UserModel.findById(userId);
return user ? user.toJSON() : null;
},
sanitizeUser: (user) => {
// Remove sensitive data before caching
const { password, ...safeUser } = user;
return safeUser;
},
logger: (message, level) => {
logger[level](`[AuthCache] ${message}`);
}
});API Reference
Core Methods
checkUser(token: string): Promise<User | null>
Verifies a JWT token and returns the cached user or fetches from database.
const user = await authCache.checkUser('eyJhbGciOiJSUzI1NiIs...');storeUser(userId: string, user: User, jwtExp?: number): void
Manually stores a user in the cache with optional JWT expiration.
authCache.storeUser('user123', { id: 'user123', name: 'John' }, Date.now() + 3600000);purgeUser(token: string): boolean
Removes a user from cache using their JWT token.
const removed = authCache.purgeUser(jwtToken);purgeByUserId(userId: string): boolean
Removes a user from cache by their user ID.
const removed = authCache.purgeByUserId('user123');middleware(): MiddlewareFunction
Creates Express-compatible middleware for automatic authentication.
app.use(authCache.middleware());middlewareWithOptions(options): MiddlewareFunction
Creates middleware with custom authentication options.
app.use('/admin', authCache.middlewareWithOptions({
required: true,
unauthorizedMessage: 'Admin access required',
unauthorizedStatusCode: 403
}));Utility Methods
getMetrics(): AuthCacheMetrics
Returns current cache performance metrics.
const metrics = authCache.getMetrics();
console.log({
hitRate: metrics.cacheHits / (metrics.cacheHits + metrics.cacheMisses),
totalUsers: metrics.totalUsers,
evictions: metrics.evictions
});getCachedUserIds(): string[]
Returns array of all cached user IDs.
getCacheSize(): number
Returns current number of users in cache.
cleanup(): void
Manually triggers cleanup of expired cache entries.
updateConfig(config: Partial<AuthCacheConfig>): void
Updates cache configuration at runtime.
Performance Characteristics
Cache Efficiency
- O(1) average time complexity for get/set operations
- LRU eviction ensures most accessed users remain cached
- TTL expiration respects JWT token lifetimes
- Memory bounded with configurable limits
Benchmarks
Based on internal testing with 10,000 users:
- Cache hit: ~0.1ms average response time
- Cache miss + DB lookup: ~15ms average response time
- Memory usage: ~50KB per 1000 cached users
- Throughput: >50,000 requests/second on modern hardware
Error Handling
AuthCache implements comprehensive error handling:
try {
const user = await authCache.checkUser(token);
if (!user) {
// Token invalid or user not found
return res.status(401).json({ error: 'Invalid token' });
}
} catch (error) {
// Network or system error
logger.error('Authentication error:', error);
return res.status(500).json({ error: 'Authentication service unavailable' });
}Error Types
- Invalid JWT: Returns
nullwithout throwing - Expired token: Returns
nulland removes from cache - Network errors: Throws exception for database fallback failures
- Configuration errors: Throws during initialization
Testing
Run the comprehensive test suite:
# Run all tests
npm test
# Run tests with coverage report
npm run test:coverage
# Run tests in watch mode
npm run test:watch
# Run linting
npm run lint
# Build the package
npm run buildTest Coverage
The package maintains high test coverage across all modules:
- 66 test cases covering core functionality
- 87% code coverage with detailed branch testing
- Integration tests for middleware and Express compatibility
- Unit tests for cache, JWT, and metrics components
Development Setup
- Clone the repository
- Install dependencies:
npm install - Run tests:
npm test - Build:
npm run build
Examples
Check the /examples directory for complete implementation examples:
- Basic Usage: Simple authentication setup
- Express Integration: Full Express.js application
- Advanced Configuration: Production-ready setup with monitoring
Performance Optimization
- Tune cache size: Set
maxUsersbased on your active user count - Adjust TTL: Balance between cache efficiency and data freshness
- Monitor metrics: Use
getMetrics()to optimize configuration - Implement cleanup: Call
cleanup()during low-traffic periods
Security
Security Considerations
- JWT tokens are never logged or cached permanently
- User data sanitization prevents sensitive information caching
- Automatic cleanup prevents memory-based token replay attacks
- Configurable algorithms prevent JWT algorithm confusion attacks
License
MIT License
