背景#
限制一定時間內的 API 存取次數,比如一分鐘內只允許存取 5 次 API。
方法#
注意:
- 透過在專案根目錄創建
middleware.ts
(或 .js) 文件來定義 Middleware。例如,與 pages 或 app 位於同一級別,或在 src 中(如果適用)。 - 一個專案只支持一個 Middleware。
專案部署在 Vercel 環境#
如果專案部署在 Vercel 上,建議參考:Add Rate Limiting with Vercel Edge Middleware and Vercel KV
專案部署在非 Vercel 環境#
以下代碼演示了:透過獲取客戶端 IP 來限制一分鐘內最多存取 5 次 /api
開頭的路由。
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const rateLimitMap = new Map()
// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
const ip = request.headers.get('x-forwarded-for') || request.ip
if (ip === '::1') return NextResponse.next()
const limit = 5 // Limiting requests to 5 per minute per IP
const windowMs = 60 * 1000 // 1 minute
if (!rateLimitMap.has(ip)) {
rateLimitMap.set(ip, {
count: 0,
lastReset: Date.now(),
})
}
const ipData = rateLimitMap.get(ip)
if (Date.now() - ipData.lastReset > windowMs) {
ipData.count = 0
ipData.lastReset = Date.now()
}
if (ipData.count >= limit) {
return NextResponse.json({ message: '請求太頻繁,請 1 分鐘後再試' }, { status: 429 })
}
ipData.count += 1
return NextResponse.next()
}
// See "Matching Paths" below to learn more
export const config = {
matcher: '/api/:path*',
}
代碼源自:Implementing Rate Limiting in Next.js API Routes without External Packages