feat: 实现统一日志系统和维护模式功能
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
const User = require('../models/User');
|
||||
const logger = require('../utils/logger').module('AuthMiddleware');
|
||||
|
||||
function getJwtSecret() {
|
||||
const envSecret = process.env.JWT_SECRET;
|
||||
@@ -124,11 +125,10 @@ const authMiddleware = async (req, res, next) => {
|
||||
user = await User.findByPk(decoded.userId);
|
||||
} catch (dbError) {
|
||||
// 数据库查询错误
|
||||
console.error('[认证中间件] 数据库查询失败:', {
|
||||
logger.error('数据库查询失败', {
|
||||
userId: decoded.userId,
|
||||
error: dbError.message,
|
||||
stack: dbError.stack,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
@@ -137,10 +137,9 @@ const authMiddleware = async (req, res, next) => {
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
console.warn('[认证中间件] 用户不存在:', {
|
||||
logger.warn('用户不存在', {
|
||||
userId: decoded.userId,
|
||||
username: decoded.username,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
@@ -149,10 +148,9 @@ const authMiddleware = async (req, res, next) => {
|
||||
}
|
||||
|
||||
if (user.status === 'locked') {
|
||||
console.warn('[认证中间件] 账户已被锁定:', {
|
||||
logger.warn('账户已被锁定', {
|
||||
userId: user.userId,
|
||||
username: user.username,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
@@ -161,10 +159,9 @@ const authMiddleware = async (req, res, next) => {
|
||||
}
|
||||
|
||||
if (user.status === 'inactive') {
|
||||
console.warn('[认证中间件] 账户已禁用:', {
|
||||
logger.warn('账户已禁用', {
|
||||
userId: user.userId,
|
||||
username: user.username,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
@@ -177,13 +174,12 @@ const authMiddleware = async (req, res, next) => {
|
||||
next();
|
||||
} catch (error) {
|
||||
// 捕获未预期的错误
|
||||
console.error('[认证中间件] 未预期的错误:', {
|
||||
logger.error('未预期的错误', {
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
url: req?.url,
|
||||
method: req?.method,
|
||||
ip: req?.ip,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
@@ -206,10 +202,9 @@ const optionalAuth = async (req, res, next) => {
|
||||
user = await User.findByPk(decoded.userId);
|
||||
} catch (dbError) {
|
||||
// 数据库错误时不中断请求,仅记录日志
|
||||
console.warn('[可选认证] 数据库查询失败:', {
|
||||
logger.warn('可选认证数据库查询失败', {
|
||||
userId: decoded.userId,
|
||||
error: dbError.message,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
// 继续执行,不设置用户信息
|
||||
next();
|
||||
@@ -226,10 +221,9 @@ const optionalAuth = async (req, res, next) => {
|
||||
next();
|
||||
} catch (error) {
|
||||
// 可选认证失败不影响主流程,仅记录日志
|
||||
console.warn('[可选认证] 认证失败(已忽略):', {
|
||||
logger.warn('可选认证失败(已忽略)', {
|
||||
error: error.message,
|
||||
url: req?.url,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
next();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
const { isMaintenanceModeActive, MaintenanceMode } = require('../utils/maintenanceMode');
|
||||
|
||||
/**
|
||||
* 维护模式中间件
|
||||
* 维护期间拦截所有非白名单请求,返回 503 状态码
|
||||
*/
|
||||
function maintenanceMiddleware(req, res, next) {
|
||||
if (!isMaintenanceModeActive()) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const isAllowed = MaintenanceMode.allowedRoutes.some((route) =>
|
||||
req.path.startsWith(route)
|
||||
);
|
||||
|
||||
if (isAllowed) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return res.status(503).json({
|
||||
success: false,
|
||||
message: '系统正在维护中,请稍后再试',
|
||||
maintenance: {
|
||||
active: true,
|
||||
reason: MaintenanceMode.reason,
|
||||
startTime: MaintenanceMode.startTime,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { maintenanceMiddleware };
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* HTTP 请求日志中间件
|
||||
* 为每个请求生成唯一 ID,记录请求/响应信息
|
||||
*/
|
||||
|
||||
const logger = require('../utils/logger');
|
||||
const crypto = require('crypto');
|
||||
|
||||
/**
|
||||
* 请求日志中间件
|
||||
* 记录每个 HTTP 请求的方法、URL、状态码、耗时、用户ID 等信息
|
||||
*/
|
||||
const requestLogger = (req, res, next) => {
|
||||
const requestId = crypto.randomBytes(4).toString('hex');
|
||||
const startTime = Date.now();
|
||||
|
||||
req.requestId = requestId;
|
||||
|
||||
res.on('finish', () => {
|
||||
const duration = Date.now() - startTime;
|
||||
const level = res.statusCode >= 500 ? 'error'
|
||||
: res.statusCode >= 400 ? 'warn' : 'debug';
|
||||
|
||||
logger[level](`${req.method} ${req.originalUrl}`, {
|
||||
module: 'HTTP',
|
||||
requestId,
|
||||
method: req.method,
|
||||
url: req.originalUrl,
|
||||
statusCode: res.statusCode,
|
||||
duration: `${duration}ms`,
|
||||
ip: req.ip || req.connection.remoteAddress,
|
||||
userAgent: req.get('User-Agent'),
|
||||
userId: req.user?.userId || null,
|
||||
});
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
module.exports = requestLogger;
|
||||
@@ -1,3 +1,5 @@
|
||||
const logger = require('../utils/logger').module('ValidationMiddleware');
|
||||
|
||||
const validate = (schema, source = 'body') => {
|
||||
return async (req, res, next) => {
|
||||
const data = source === 'query' ? req.query : req.body;
|
||||
@@ -73,7 +75,7 @@ const validate = (schema, source = 'body') => {
|
||||
});
|
||||
}
|
||||
|
||||
console.error('验证中间件错误:', error);
|
||||
logger.error('验证中间件错误', { error: error.message, stack: error.stack });
|
||||
return res.status(500).json({
|
||||
error: '验证过程发生错误',
|
||||
message: error.message,
|
||||
|
||||
Reference in New Issue
Block a user