require('dotenv').config(); const express = require('express'); const mongoose = require('mongoose'); const cors = require('cors'); const helmet = require('helmet'); const rateLimit = require('express-rate-limit'); const app = express(); const PORT = process.env.PORT || 3000; // ─── 安全中间件 ────────────────────────────────────────────── // helmet: 安全响应头 app.use(helmet()); // CORS: 白名单域名 const allowedOrigins = (process.env.ALLOWED_ORIGINS || 'http://localhost:5173') .split(',') .map((o) => o.trim()); app.use(cors({ origin: allowedOrigins, credentials: true })); // 请求体大小限制(防止大body攻击) app.use(express.json({ limit: '10kb' })); app.use(express.urlencoded({ extended: true, limit: '10kb' })); // 全局限流(所有 API) const globalLimiter = rateLimit({ windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000, max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 100, standardHeaders: true, legacyHeaders: false, message: { success: false, message: '请求过于频繁,请稍后再试' } }); app.use('/api', globalLimiter); // 登录接口更严格的限流(单独限流器) const loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 20, standardHeaders: true, legacyHeaders: false, message: { success: false, message: '登录尝试过于频繁,请15分钟后再试' } }); // ─── 连接 MongoDB ──────────────────────────────────────────── mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/e-scooter-rental') .then(() => console.log('✅ MongoDB 连接成功')) .catch(err => console.error('❌ MongoDB 连接失败:', err.message)); // ─── 路由 ─────────────────────────────────────────────────── app.use('/api/vehicles', require('./routes/vehicles')); app.use('/api/orders', require('./routes/orders')); app.use('/api/customers', require('./routes/customers')); app.use('/api/finance', require('./routes/finance')); app.use('/api/stores', require('./routes/stores')); app.use('/api/complaints', require('./routes/complaints')); app.use('/api/approvals', require('./routes/approvals')); app.use('/api/payments', require('./routes/payments')); app.use('/api/conflicts', require('./routes/conflicts')); app.use('/api/applications', require('./routes/applications')); app.use('/api/disputes', require('./routes/disputes')); app.use('/api/riders', require('./routes/riders')); app.use('/api/vehicle-types', require('./routes/vehicleTypes')); // ─── 健康检查(不限流) ───────────────────────────────────── app.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); // ─── 404 处理 ─────────────────────────────────────────────── app.use((req, res) => { res.status(404).json({ success: false, message: '接口不存在', path: req.path }); }); // ─── 错误处理中间件 ───────────────────────────────────────── const errorHandler = require('./middleware/errorHandler'); app.use(errorHandler); // ─── 启动 ─────────────────────────────────────────────────── app.listen(PORT, () => { console.log(`🚀 服务器运行在 http://localhost:${PORT}`); });