Overview
The E-commerce API implements rate limiting to prevent abuse and ensure fair usage across all clients. Rate limiting is particularly critical for authentication endpoints to protect against brute force attacks.
Authentication Rate Limiting
Authentication endpoints have strict rate limits to prevent credential stuffing and brute force attacks.
Configuration
The API uses express-rate-limit middleware with the following configuration:
import rateLimit from "express-rate-limit";
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 10, // maximum 10 attempts per window
message: { error: "Too many attempts. Try again in 15 minutes." },
standardHeaders: true,
legacyHeaders: false,
});
Users are limited to 10 authentication attempts per 15-minute window. Exceeding this limit will result in a 429 (Too Many Requests) response.
Protected Endpoints
The rate limiter is applied to the following authentication endpoints:
POST /auth/register - User registration
POST /auth/login - User login
From backend/src/routes/auth.routes.ts:23-24:
router.post("/register", authLimiter, validateDto(CreateUserDto), controller.register);
router.post("/login", authLimiter, validateDto(LoginUserDto), controller.login);
When rate limiting is active, the API returns standard rate limit headers:
RateLimit-Limit: 10
RateLimit-Remaining: 7
RateLimit-Reset: 1678901234
| Header | Description |
|---|
RateLimit-Limit | Maximum number of requests allowed in the window |
RateLimit-Remaining | Number of requests remaining in the current window |
RateLimit-Reset | Unix timestamp when the rate limit window resets |
Monitor the RateLimit-Remaining header to implement client-side backoff strategies and avoid hitting rate limits.
Error Response
When the rate limit is exceeded, the API returns:
{
"error": "Too many attempts. Try again in 15 minutes."
}
Status Code: 429 Too Many Requests
Best Practices
For API Consumers
- Implement Exponential Backoff: When you receive a 429 response, wait before retrying
- Cache Tokens: Store JWT tokens securely and reuse them instead of logging in repeatedly
- Monitor Headers: Check
RateLimit-Remaining to avoid hitting limits
- Handle Errors Gracefully: Display user-friendly messages when rate limits are hit
For API Administrators
Consider implementing different rate limit tiers for authenticated vs. unauthenticated requests, or offering higher limits for premium users.
Testing Rate Limits
You can test rate limiting behavior with the following curl command:
for i in {1..11}; do
echo "Request $i:"
curl -X POST https://api.example.com/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"wrongpassword"}' \
-w "\nStatus: %{http_code}\n\n"
done
The 11th request should return a 429 status code.
Custom Rate Limiting
To implement custom rate limiting for other endpoints:
import rateLimit from "express-rate-limit";
const apiLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 100, // 100 requests per minute
message: { error: "Rate limit exceeded" },
standardHeaders: true,
legacyHeaders: false,
});
// Apply to all routes
app.use("/api", apiLimiter);
// Or to specific routes
router.get("/products", apiLimiter, controller.list);
Always apply rate limiting to public endpoints that don’t require authentication, as they are more vulnerable to abuse.