
- Updated `.env` and added `.env.test` for environment variables. - Introduced API documentation in `API_DOCUMENTATION.md`. - Added authentication setup guide in `AUTHENTICATION_SETUP.md`. - Implemented user authentication with JWT and email verification. - Created new routes for user management and form submissions. - Added middleware for API key authentication and error handling. - Set up Redis for rate limiting and notifications. - Removed obsolete files and configurations related to the previous Rust implementation.
4.5 KiB
4.5 KiB
Rate Limiting Documentation
Overview
This application now implements a scalable Redis-backed rate limiting system to protect against abuse and ensure fair usage of the form submission endpoints.
Rate Limiting Strategy
The /submit/:formUuid
endpoint is protected by three layers of rate limiting:
1. Strict Rate Limiter (First Layer)
- Window: 1 hour
- Limit: 50 requests per IP address across all forms
- Purpose: Prevents aggressive abuse from single IP addresses
- Key:
strict_ip:{ip_address}
2. General Submission Rate Limiter (Second Layer)
- Window: 15 minutes
- Limit: 10 requests per IP address for any form submissions
- Purpose: Prevents rapid-fire submissions from legitimate users
- Key:
submit_ip:{ip_address}
3. Form-Specific Rate Limiter (Third Layer)
- Window: 5 minutes
- Limit: 3 requests per IP address per specific form
- Purpose: Prevents spam on individual forms
- Key:
submit_form:{formUuid}:{ip_address}
Infrastructure
Redis Configuration
Development Environment
- Service:
redis:7-alpine
- Port:
6379
- Data Persistence: Yes (Redis AOF)
- Volume:
redis_data:/data
Production Environment
- Service:
redis:7-alpine
- Port:
6380
(external, to avoid conflicts) - Data Persistence: Yes (Redis AOF)
- Volume:
redis_data:/data
- Password Protection: Configurable via
REDIS_PASSWORD
- Health Checks: Enabled
Environment Variables
# Redis Configuration
REDIS_HOST=redis # Redis hostname (default: redis in Docker, localhost otherwise)
REDIS_PORT=6379 # Redis port (default: 6379)
REDIS_PASSWORD= # Optional Redis password (production recommended)
Fallback Mechanism
If Redis is unavailable, the system automatically falls back to an in-memory rate limiter:
- Graceful Degradation: Application continues to function without Redis
- Automatic Detection: Detects Redis availability and switches accordingly
- Logging: Warns when falling back to memory store
- Same Limits: Maintains the same rate limiting rules
Rate Limit Headers
When rate limits are applied, the following headers are returned:
RateLimit-Limit
: Maximum number of requests allowedRateLimit-Remaining
: Number of requests remaining in windowRateLimit-Reset
: Time when the rate limit window resets
Error Responses
When rate limits are exceeded, the API returns:
{
"error": "Too many requests from this IP address. Please try again later."
}
The specific error message varies by rate limiter:
- Strict: "Too many requests from this IP address. Please try again later."
- General: "Too many form submissions from this IP address. Please try again later."
- Form-Specific: "Too many submissions for this form from your IP address. Please try again later."
Deployment
Starting Services
Development
docker-compose up -d
Production
docker-compose -f docker-compose.prod.yml up -d
Monitoring Redis
Check Redis connection:
docker exec -it formies-redis-1 redis-cli ping
View rate limiting keys:
docker exec -it formies-redis-1 redis-cli --scan --pattern "submit_*"
Security Considerations
- Redis Security: In production, always use password authentication
- Network Security: Redis should not be exposed to public networks
- Data Persistence: Redis data is persisted to handle container restarts
- Graceful Shutdown: Application properly closes Redis connections on exit
Performance
- Scalability: Redis-backed rate limiting scales across multiple application instances
- Efficiency: O(1) operations for rate limit checks
- Memory Usage: Efficient key expiration prevents memory leaks
- High Availability: Can be configured with Redis clustering for production
Troubleshooting
Common Issues
-
Redis Connection Failed
- Check if Redis container is running
- Verify environment variables
- Check Docker network connectivity
-
Rate Limiting Not Working
- Verify Redis connection in application logs
- Check if fallback to memory store is occurring
- Ensure proper IP address detection
-
Performance Issues
- Monitor Redis memory usage
- Check for connection pooling configuration
- Verify network latency between app and Redis
Logs to Monitor
- Redis connection status
- Rate limiter fallback warnings
- Rate limit exceeded events
- Redis error messages