Skip to main content

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);

Rate Limit Headers

When rate limiting is active, the API returns standard rate limit headers:
RateLimit-Limit: 10
RateLimit-Remaining: 7
RateLimit-Reset: 1678901234
HeaderDescription
RateLimit-LimitMaximum number of requests allowed in the window
RateLimit-RemainingNumber of requests remaining in the current window
RateLimit-ResetUnix 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

  1. Implement Exponential Backoff: When you receive a 429 response, wait before retrying
  2. Cache Tokens: Store JWT tokens securely and reuse them instead of logging in repeatedly
  3. Monitor Headers: Check RateLimit-Remaining to avoid hitting limits
  4. 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.

Build docs developers (and LLMs) love