Next.js 15 边缘速率限制与机器人防护实践概述在边缘层进行速率限制与机器人防护可最大化节省后端资源。本文给出 Middleware 令牌桶实现、挑战页(简化)与缓存键治理方案。令牌桶实现(KV 存储)// middleware.ts(简化示例)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const RATE = 60 // 每分钟允许请求数
const WINDOW = 60_000
async function allow(ip: string) {
const key = `rate:${ip}`
const now = Date.now()
const bucket = (await kv.get(key)) || { tokens: RATE, ts: now }
const elapsed = now - bucket.ts
const refill = Math.floor(elapsed / (WINDOW / RATE))
bucket.tokens = Math.min(RATE, bucket.tokens + refill)
bucket.ts = now
if (bucket.tokens <= 0) return false
bucket.tokens -= 1
await kv.set(key, bucket, { ttl: 300 })
return true
}
function isBot(req: NextRequest) {
const ua = req.headers.get('user-agent') || ''
const badUA = /(crawler|spider|bot|scrape)/i.test(ua)
const acceptLang = req.headers.get('accept-language') || ''
return badUA || acceptLang.length === 0
}
export async function middleware(req: NextRequest) {
const ip = req.ip || req.headers.get('x-forwarded-for') || 'unknown'
const ok = await allow(String(ip))
if (!ok) return NextResponse.json({ error: 'Too Many Requests' }, { status: 429 })
if (isBot(req)) {
const url = req.nextUrl.clone()
url.pathname = '/challenge'
return NextResponse.rewrite(url)
}
return NextResponse.next()
}
export const config = { matcher: ['/((?!_next|static|api|challenge).*)'] }
挑战页(简化)// app/challenge/page.tsx
export default function Challenge() {
return (
<main>
<h1>验证访问</h1>
<p>请完成简单交互以继续。</p>
{/* 实际可接入更完善的人机验证机制 */}
</main>
)
}
缓存键治理速率限制错误不缓存;挑战页缓存短时并标记用户通过后发放 cookie;CDN 缓存键包含 `challenge=ok` 参数以区分。技术参数与验证边缘延迟:令牌桶计算 < 1ms;挑战路径有效拦截异常流量指标:429 响应率按需控制;正常用户误拦截率 < 0.1%注意事项结合地理与 UA 白名单;对 API 与静态资源设置独立策略日志与告警接入;遵循隐私与合规参考资料Next.js Edge Middleware 文档;速率限制与机器人防护最佳实践---发布信息:已发布 · 技术验证 · 阅读 36 分钟 · CC BY-SA 4.0

发表评论 取消回复