Nuxt API Shield
このNuxtモジュールは、過剰なリクエストからAPIエンドポイントを保護するためのレート制限ミドルウェアを実装します。
機能
- IPベースのレート制限とブルートフォース攻撃対策
- 個々のIPアドレスのレート制限を追跡し、適用します。
- 単一ソースからの悪意のある行為者または過剰なリクエストがAPIを圧倒するのを防ぎます。
- カスタマイズ可能なレート制限
- 最大リクエスト数、制限が適用される期間、および制限を超えた場合の禁止期間を設定できます。
- ユーザーが禁止されている場合、さらなる不正使用を阻止するために、レスポンスに遅延を追加します。
- 禁止されたユーザー向けのエラーメッセージをカスタマイズできます。
- ユーザーが禁止されている場合、レスポンスに
Retry-After
ヘッダーを含めるオプションがあります。 - APIの特定のニーズと使用パターンに合わせて、レート制限の動作を調整できます。
- イベント駆動型処理
- Nuxtのイベントシステムを使用して、着信APIリクエストを効率的にインターセプトします。
- Nuxtアプリケーションのリクエストライフサイクルとのシームレスな統合を保証します。
- 柔軟なストレージ
- 多様なストレージオプションのために、Nuxtのunstorage抽象化を利用します。
- プロジェクトの要件に基づいて、さまざまなストレージプロバイダー(ファイルシステム、メモリ、データベースなど)にレート制限データを保存します。
- ランタイム設定で構成可能
- コードを変更せずに、レート制限パラメーターを簡単に調整できます。
- 動的なニーズに適応し、Nuxtのランタイム設定を通じてレート制限の動作を制御します。
- 明確なエラー処理
- レート制限を超えた場合、標準化された429「Too Many Requests」エラーレスポンスを返します。
- スムーズなユーザーエクスペリエンスのために、クライアントサイドアプリケーションでの適切なエラー処理を容易にします。
迅速なセットアップ
1. プロジェクトにnuxt-api-shield
依存関係を追加します。
# Using pnpm
pnpm add nuxt-api-shield
# Using yarn
yarn add nuxt-api-shield
# Using npm
npm install nuxt-api-shield
2. nuxt.config.ts
のmodules
セクションにnuxt-api-shield
を追加します。
デフォルト値と異なる値のみを追加する必要があります。
export default defineNuxtConfig({
modules: ["nuxt-api-shield"],
nuxtApiShield: {
/*limit: {
max: 12, // maximum requests per duration time, default is 12/duration
duration: 108, // duration time in seconds, default is 108 seconds
ban: 3600, // ban time in seconds, default is 3600 seconds = 1 hour
},
delayOnBan: true // delay every response with +1sec when the user is banned, default is true
errorMessage: "Too Many Requests", // error message when the user is banned, default is "Too Many Requests"
retryAfterHeader: false, // when the user is banned add the Retry-After header to the response, default is false
log: {
path: "logs", // path to the log file, every day a new log file will be created, use "" to disable logging
attempts: 100, // if an IP reach 100 requests, all the requests will be logged, can be used for further analysis or blocking for example with fail2ban, use 0 to disable logging
},
routes: [], // specify routes to apply rate limiting to, default is an empty array meaning all routes are protected.
// Example:
// routes: ["/api/v2/", "/api/v3/"], // /api/v1 will not be protected, /api/v2/ and /api/v3/ will be protected */
},
});
3. nuxt.config.ts
にnitro/storage
を追加します。
任意のストレージを使用できますが、ストレージの名前としてshieldを使用する必要があります。
{
"nitro": {
"storage": {
"shield": {
// storage name, you **must** use "shield" as the name
"driver": "memory"
}
}
}
}
4. nuxt.config.ts
にshield:clean
を追加します。
{
"nitro": {
"experimental": {
"tasks": true
},
"scheduledTasks": {
"*/15 * * * *": ["shield:clean"] // clean the shield storage every 15 minutes
}
}
}
5. clean
タスクを作成します。
server/tasks/shield/clean.ts
には、次のようなものが必要です。
import type { RateLimit } from "#imports";
export default defineTask({
meta: {
description: "Clean expired bans",
},
async run() {
const shieldStorage = useStorage("shield");
const keys = await shieldStorage.getKeys();
keys.forEach(async (key) => {
const rateLimit = (await shieldStorage.getItem(key)) as RateLimit;
if (isBanExpired(rateLimit)) {
await shieldStorage.removeItem(key);
}
});
return { result: keys };
},
});
開発
# Install dependencies
yarn
# Generate type stubs
yarn dev:prepare
# Develop with the playground
yarn dev
# Build the playground
yarn dev:build
# Run ESLint
yarn lint
# Run Vitest
yarn test
yarn test:watch
# Release new version
yarn release:patch
yarn release:minor