fix: relax canvas read api rate limits
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-03-25 15:39:54 +08:00
parent 23c326b1fb
commit 3864cf7ff8
2 changed files with 25 additions and 1 deletions

View File

@ -13,7 +13,7 @@ export async function generateMetadata(): Promise<Metadata> {
const updatedAt =
"updatedAt" in settings && settings.updatedAt
? new Date(settings.updatedAt).getTime()
: Date.now();
: "default";
const faviconUrl = `/api/favicon?v=${updatedAt}`;
const metadataBase = process.env.AUTH_URL
? new URL(process.env.AUTH_URL)

View File

@ -11,15 +11,19 @@ import { isSuspiciousRequest, logSuspiciousRequest } from "@/lib/security/reques
function isHighFrequencyReadApi(pathname: string, method: string) {
if (method !== "GET") return false;
if (/^\/api\/canvas\/[^/]+\/detail-archives$/.test(pathname)) return true;
if (/^\/api\/canvas\/[^/]+$/.test(pathname)) return true;
return [
"/api/models",
"/api/canvas",
"/api/canvas-skill-tags",
"/api/nav-links",
"/api/site-settings",
"/api/messages",
"/api/history",
"/api/vote",
"/api/video-tasks",
"/api/user/image-stats",
"/api/tutorial-videos",
"/api/user/membership-summary",
"/api/user/account-center",
@ -63,6 +67,11 @@ export async function proxy(request: NextRequest) {
// 可以在这里添加更严格的检查
}
// 浏览器会自动拉取 favicon,不应参与通用 API 限流。
if (pathname === "/api/favicon") {
return NextResponse.next();
}
// 🛡️ 安全检查3:速率限制
// 对API路径应用速率限制
if (pathname === "/api/chat") {
@ -126,6 +135,21 @@ export async function proxy(request: NextRequest) {
{ status: 429 }
);
}
} else if (pathname === "/api/canvas/auto-title" && request.method === "POST") {
const canvasRateLimit = checkRateLimit(request, rateLimiters.canvas);
if (!canvasRateLimit.allowed) {
console.warn(`[Security] Canvas auto-title rate limit exceeded for IP: ${clientIP}`, {
pathname,
resetTime: new Date(canvasRateLimit.resetTime).toISOString(),
});
return NextResponse.json(
{
error: "Too many canvas requests",
retryAfter: Math.ceil((canvasRateLimit.resetTime - Date.now()) / 1000),
},
{ status: 429 }
);
}
} else if (
pathname.startsWith("/api/realtime/") ||
pathname.startsWith("/api/fal/proxy")