v0.3.2: fix 401 on save-records fetch + fix 429 rate limiter behind proxy
- AdminDashboard: M() now sends admin_token from localStorage with fetch - rate-limit: keyGenerator uses req.ip instead of req.socket.remoteAddress (Express trust proxy reads X-Forwarded-For for real client IP) - main.ts: moved global rateLimiter after express.static so static files (JS/CSS/admin page/favicon) are never rate-limited
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -38,8 +38,6 @@ app.use(morgan(':method :url :status :res[content-length] - :response-time ms'))
|
|||||||
|
|
||||||
app.use(express.json({ limit: '10mb' }));
|
app.use(express.json({ limit: '10mb' }));
|
||||||
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
||||||
app.use(rateLimiter);
|
|
||||||
|
|
||||||
// ============ 前端静态文件 ============
|
// ============ 前端静态文件 ============
|
||||||
const frontendDist = path.join(__dirname, 'frontend');
|
const frontendDist = path.join(__dirname, 'frontend');
|
||||||
// Cache control: HTML no-cache, hashed assets immutable
|
// Cache control: HTML no-cache, hashed assets immutable
|
||||||
@@ -53,6 +51,9 @@ app.use((req, res, next) => {
|
|||||||
});
|
});
|
||||||
app.use(express.static(frontendDist));
|
app.use(express.static(frontendDist));
|
||||||
|
|
||||||
|
// ============ Rate Limiting (after static files — only API routes are limited)
|
||||||
|
app.use(rateLimiter);
|
||||||
|
|
||||||
// ============ Routes ============
|
// ============ Routes ============
|
||||||
app.use('/api/uploads', express.static('/app/uploads'));
|
app.use('/api/uploads', express.static('/app/uploads'));
|
||||||
app.use('/api', routes);
|
app.use('/api', routes);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export const searchLimiter = rateLimit({
|
|||||||
max: 150,
|
max: 150,
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
keyGenerator: (req) => req.socket.remoteAddress ?? 'unknown',
|
keyGenerator: (req) => req.ip ?? 'unknown',
|
||||||
message: { error: '搜索请求过于频繁,请稍后再试', code: 429 },
|
message: { error: '搜索请求过于频繁,请稍后再试', code: 429 },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ export const adminLimiter = rateLimit({
|
|||||||
max: 30,
|
max: 30,
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
keyGenerator: (req) => req.socket.remoteAddress ?? 'unknown',
|
keyGenerator: (req) => req.ip ?? 'unknown',
|
||||||
message: { error: '操作过于频繁,请稍后再试', code: 429 },
|
message: { error: '操作过于频繁,请稍后再试', code: 429 },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ export const loginLimiter = rateLimit({
|
|||||||
max: 5,
|
max: 5,
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
keyGenerator: (req) => req.socket.remoteAddress ?? 'unknown',
|
keyGenerator: (req) => req.ip ?? 'unknown',
|
||||||
message: { error: '登录尝试次数过多,请一分钟后重试', code: 429 },
|
message: { error: '登录尝试次数过多,请一分钟后重试', code: 429 },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ export const saveLimiter = rateLimit({
|
|||||||
max: 30,
|
max: 30,
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
keyGenerator: (req) => req.socket.remoteAddress ?? 'unknown',
|
keyGenerator: (req) => req.ip ?? 'unknown',
|
||||||
message: { error: '转存操作过于频繁,请稍后再试', code: 429 },
|
message: { error: '转存操作过于频繁,请稍后再试', code: 429 },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -46,11 +46,11 @@ const defaultLimiter = rateLimit({
|
|||||||
max: 100,
|
max: 100,
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
keyGenerator: (req) => req.socket.remoteAddress ?? 'unknown',
|
keyGenerator: (req) => req.ip ?? 'unknown',
|
||||||
message: { error: 'Too many requests, please try again later.', code: 429 },
|
message: { error: 'Too many requests, please try again later.', code: 429 },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default defaultLimiter;
|
export default defaultLimiter;
|
||||||
|
|
||||||
// NOTE v0.2.8: Fixed keyGenerator to use getClientIP() instead of req.socket.remoteAddress
|
// v0.3.2: Fixed keyGenerator to use req.ip (Express trust proxy reads X-Forwarded-For)
|
||||||
// This ensures rate limiting works correctly behind reverse proxy (OpenResty)
|
// This ensures rate limiting works correctly behind reverse proxy (OpenResty)
|
||||||
|
|||||||
Reference in New Issue
Block a user