fix: separate admin api rate limiting

This commit is contained in:
Your Name 2026-05-28 10:08:30 +08:00
parent 4941f09dfa
commit 2eba3d8b5e
2 changed files with 27 additions and 0 deletions

View File

@ -77,6 +77,9 @@ export const rateLimiters = {
// 通用API限制:每分钟100次请求
api: new RateLimiter(60000, 100),
// 管理后台接口:设置页会并发加载大量配置,不能和公开 API 共用低阈值
admin: new RateLimiter(60000, 3000),
// 文件上传接口:每分钟60次请求(独立于通用API限流)
upload: new RateLimiter(60000, 60),

View File

@ -191,6 +191,30 @@ export async function proxy(request: NextRequest) {
{ status: 429 }
);
}
} else if (pathname.startsWith("/api/admin/")) {
const token = await resolveToken();
const adminIdentifier =
typeof token?.sub === "string" && token.sub.length > 0
? `admin:${token.sub}`
: `admin-ip:${clientIP}`;
const adminRateLimit = checkRateLimitByIdentifier(
adminIdentifier,
rateLimiters.admin
);
if (!adminRateLimit.allowed) {
const retryAfter = Math.max(
1,
Math.ceil((adminRateLimit.resetTime - Date.now()) / 1000)
);
console.warn(`[Security] Admin rate limit exceeded for IP: ${clientIP}`, {
pathname,
resetTime: new Date(adminRateLimit.resetTime).toISOString(),
});
return NextResponse.json(
{ error: "Too many admin requests", retryAfter },
{ status: 429, headers: { "Retry-After": String(retryAfter) } }
);
}
} else if (pathname.startsWith("/api/")) {
const rateLimit = checkRateLimit(request, rateLimiters.api);
if (!rateLimit.allowed) {