rate-limiting-abuse-protection

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Rate Limiting & Abuse Protection

速率限制与滥用防护

Protect APIs from abuse with intelligent rate limiting.
通过智能速率限制保护API免受滥用。

Rate Limit Strategies

速率限制策略

Fixed Window: 100 requests per hour Sliding Window: More accurate, prevents bursts Token Bucket: Allow bursts up to limit Leaky Bucket: Smooth request rate
固定窗口:每小时100次请求 滑动窗口:更精准,防止突发流量 令牌桶:允许在限制内的突发请求 漏桶:平滑请求速率

Implementation (Express)

Express实现

typescript
import rateLimit from "express-rate-limit";

// Global rate limit
const globalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // 100 requests per window
  message: "Too many requests, please try again later",
  standardHeaders: true, // Return rate limit info in headers
  legacyHeaders: false,
});

// Stricter limit for auth endpoints
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5, // Only 5 attempts
  skipSuccessfulRequests: true, // Don't count successful logins
});

app.use("/api/", globalLimiter);
app.use("/api/auth/login", authLimiter);
typescript
import rateLimit from "express-rate-limit";

// Global rate limit
const globalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // 100 requests per window
  message: "Too many requests, please try again later",
  standardHeaders: true, // Return rate limit info in headers
  legacyHeaders: false,
});

// Stricter limit for auth endpoints
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5, // Only 5 attempts
  skipSuccessfulRequests: true, // Don't count successful logins
});

app.use("/api/", globalLimiter);
app.use("/api/auth/login", authLimiter);

Redis-based Rate Limiting

基于Redis的速率限制

typescript
import Redis from "ioredis";

const redis = new Redis();

export const checkRateLimit = async (
  key: string,
  max: number,
  window: number
): Promise<{ allowed: boolean; remaining: number }> => {
  const now = Date.now();
  const windowStart = now - window;

  await redis
    .multi()
    .zremrangebyscore(key, 0, windowStart)
    .zadd(key, now, `${now}`)
    .zcard(key)
    .expire(key, Math.ceil(window / 1000))
    .exec();

  const count = await redis.zcard(key);

  return {
    allowed: count <= max,
    remaining: Math.max(0, max - count),
  };
};
typescript
import Redis from "ioredis";

const redis = new Redis();

export const checkRateLimit = async (
  key: string,
  max: number,
  window: number
): Promise<{ allowed: boolean; remaining: number }> => {
  const now = Date.now();
  const windowStart = now - window;

  await redis
    .multi()
    .zremrangebyscore(key, 0, windowStart)
    .zadd(key, now, `${now}`)
    .zcard(key)
    .expire(key, Math.ceil(window / 1000))
    .exec();

  const count = await redis.zcard(key);

  return {
    allowed: count <= max,
    remaining: Math.max(0, max - count),
  };
};

Per-User Rate Limiting

基于用户的速率限制

typescript
export const userRateLimit = (max: number, window: number) => {
  return async (req, res, next) => {
    if (!req.user) return next();

    const key = `rate_limit:user:${req.user.id}`;
    const result = await checkRateLimit(key, max, window);

    res.setHeader("X-RateLimit-Limit", max);
    res.setHeader("X-RateLimit-Remaining", result.remaining);

    if (!result.allowed) {
      return res.status(429).json({
        error: "Rate limit exceeded",
        retryAfter: window / 1000,
      });
    }

    next();
  };
};
typescript
export const userRateLimit = (max: number, window: number) => {
  return async (req, res, next) => {
    if (!req.user) return next();

    const key = `rate_limit:user:${req.user.id}`;
    const result = await checkRateLimit(key, max, window);

    res.setHeader("X-RateLimit-Limit", max);
    res.setHeader("X-RateLimit-Remaining", result.remaining);

    if (!result.allowed) {
      return res.status(429).json({
        error: "Rate limit exceeded",
        retryAfter: window / 1000,
      });
    }

    next();
  };
};

IP-based Protection

基于IP的防护

typescript
// Block suspicious IPs
const ipBlocklist = new Set<string>();

export const checkIPReputation = async (ip: string): Promise<boolean> => {
  if (ipBlocklist.has(ip)) return false;

  // Check against threat intelligence API
  const reputation = await checkThreatIntel(ip);
  if (reputation.isMalicious) {
    ipBlocklist.add(ip);
    return false;
  }

  return true;
};
typescript
// Block suspicious IPs
const ipBlocklist = new Set<string>();

export const checkIPReputation = async (ip: string): Promise<boolean> => {
  if (ipBlocklist.has(ip)) return false;

  // Check against threat intelligence API
  const reputation = await checkThreatIntel(ip);
  if (reputation.isMalicious) {
    ipBlocklist.add(ip);
    return false;
  }

  return true;
};

Response Headers

响应头

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640000000
Retry-After: 3600
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640000000
Retry-After: 3600

Best Practices

最佳实践

  • Different limits for different endpoints
  • Lower limits for expensive operations
  • Skip rate limit for internal services
  • Return helpful error messages
  • Log rate limit violations
  • Monitor for abuse patterns
  • Allowlist trusted IPs
  • 为不同端点设置不同的限制
  • 对资源密集型操作设置更低的限制
  • 为内部服务跳过速率限制
  • 返回有用的错误信息
  • 记录速率限制违规情况
  • 监控滥用模式
  • 将可信IP加入白名单

Output Checklist

输出检查清单

  • Rate limiter middleware
  • Per-route policies
  • User-based limiting
  • IP-based limiting
  • Rate limit headers
  • Safe error responses
  • Observability/logging
  • Bypass for internal services
  • 速率限制中间件
  • 路由级策略
  • 基于用户的限制
  • 基于IP的限制
  • 速率限制响应头
  • 安全错误响应
  • 可观测性/日志记录
  • 内部服务绕过机制