【Node.js】大量リクエストを高速処理するRate Limiterの実装法|Express中間処理で防御力UP

【Node.js】大量リクエストを高速処理するRate Limiterの実装法|Express中間処理で防御力UP Node.js

APIサーバーにおいて、外部からの過剰なリクエストによってリソースが枯渇する事態は珍しくありません。特にNode.jsのように非同期で高速にリクエストを処理できる環境では、同時接続数や負荷に対する防御策が欠かせません。

本記事では、Expressフレームワークを用いて、Rate Limiter(レート制限)を中間処理として実装し、大量アクセスに対する防御力を高める手法を解説します。

なぜRate Limiterが必要なのか

以下のような状況でRate Limiterの導入が有効です。

  • 短時間に特定IPから大量アクセスが発生
  • BotによるAPIスパム攻撃やDoSの初期防衛
  • ユーザーごとのAPI使用制限(無料枠制限など)

レートリミットは、アプリケーション層で実装でき、軽量なミドルウェアとして機能します。

express-rate-limitの導入

最も手軽な実装は、express-rate-limitというパッケージを使う方法です。

npm install express-rate-limit

続いて、以下のようにミドルウェアとして設定します。

const express = require('express');
const rateLimit = require('express-rate-limit');

const app = express();

// レートリミッターの設定
const limiter = rateLimit({
  windowMs: 1 * 60 * 1000, // 1分間
  max: 100, // 1分間に最大100件
  standardHeaders: true,
  legacyHeaders: false,
  message: 'リクエストが多すぎます。しばらくしてから再試行してください。'
});

// 全てのルートに適用
app.use(limiter);

app.get('/', (req, res) => {
  res.send('正常アクセス');
});

app.listen(3000, () => {
  console.log('サーバー起動中');
});

上記の例では、「1分間に100リクエスト」までを許容し、それを超えた場合はHTTP 429エラーを返します。

特定ルートのみ制限をかける

ログインや検索など、負荷が高い特定のエンドポイントだけに適用することも可能です。

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分
  max: 5, // 最大5回の試行
  message: 'ログイン試行が多すぎます。15分後に再試行してください。'
});

app.post('/login', loginLimiter, (req, res) => {
  // ログイン処理
});

これにより、ログインフォームの不正連打(ブルートフォース攻撃)を防ぐことができます。

IPアドレス単位で制限される仕組み

デフォルトでは、クライアントのIPアドレスを識別して制限をかけます。プロキシやCDN環境ではtrust proxy設定が必要です。

app.set('trust proxy', 1); // Heroku, Vercelなどを使用する場合

Redisなどを活用した永続化

デフォルトでは、メモリ上でカウントが管理されるため、プロセス再起動でリセットされます。Redisなどのストアと連携することで、スケーラブルな環境に対応可能です。

たとえば、rate-limit-redisとの併用で以下のような構成が可能です:

npm install rate-limit-redis ioredis
const RedisStore = require('rate-limit-redis');
const Redis = require('ioredis');

const redisClient = new Redis();

const limiter = rateLimit({
  store: new RedisStore({
    sendCommand: (...args) => redisClient.call(...args)
  }),
  windowMs: 1 * 60 * 1000,
  max: 100,
});

まとめ|Expressにおける防御の第一歩として

Node.js + Express で運用するAPIにおいて、Rate Limiterの導入はセキュリティ対策とリソース保護の両面で非常に有効です。

簡易な実装で導入可能でありながら、大量アクセスへの初期防衛策として高い効果を発揮します。Redisとの併用でクラスタ環境にも対応可能です。

今後、認証・APIキー・ログ集計と組み合わせた、より高度な利用制限を実現する土台としても活用できます。