Initial commit: 宁夏智慧养殖监管平台
This commit is contained in:
90
backend/middleware/auth.js
Normal file
90
backend/middleware/auth.js
Normal file
@@ -0,0 +1,90 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
const { User, Role } = require('../models');
|
||||
|
||||
/**
|
||||
* 验证JWT Token的中间件
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
* @param {Function} next - 下一步函数
|
||||
*/
|
||||
const verifyToken = async (req, res, next) => {
|
||||
try {
|
||||
// 从请求头获取token
|
||||
const authHeader = req.headers['authorization'];
|
||||
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
message: '未授权'
|
||||
});
|
||||
}
|
||||
|
||||
// 验证token
|
||||
const decoded = jwt.verify(token, process.env.JWT_SECRET || 'your_jwt_secret_key');
|
||||
|
||||
// 将用户信息添加到请求对象中
|
||||
req.user = decoded;
|
||||
next();
|
||||
} catch (error) {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
message: '未授权'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 检查用户是否具有指定角色的中间件
|
||||
* @param {string[]} roles - 允许访问的角色数组
|
||||
* @returns {Function} 中间件函数
|
||||
*/
|
||||
const checkRole = (roles) => {
|
||||
return async (req, res, next) => {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
|
||||
// 查询用户及其角色
|
||||
const user = await User.findByPk(userId, {
|
||||
include: [{
|
||||
model: Role,
|
||||
as: 'roles', // 添加as属性,指定关联别名
|
||||
attributes: ['name']
|
||||
}]
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '用户不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户角色名称数组
|
||||
const userRoles = user.roles.map(role => role.name);
|
||||
|
||||
// 检查用户是否具有所需角色
|
||||
const hasRequiredRole = roles.some(role => userRoles.includes(role));
|
||||
|
||||
if (!hasRequiredRole) {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
message: '权限不足'
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
console.error('角色检查错误:', error);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
message: '服务器内部错误'
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
verifyToken,
|
||||
checkRole
|
||||
};
|
||||
90
backend/middleware/performance-middleware.js
Normal file
90
backend/middleware/performance-middleware.js
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* API性能监控中间件
|
||||
* @file performance-middleware.js
|
||||
* @description 用于监控API请求性能的Express中间件
|
||||
*/
|
||||
const { performanceMonitor, events: perfEvents } = require('../utils/performance-monitor');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
/**
|
||||
* API性能监控中间件
|
||||
* 记录请求的响应时间、状态码和错误率
|
||||
*/
|
||||
function apiPerformanceMonitor(req, res, next) {
|
||||
// 记录请求开始时间
|
||||
const startTime = Date.now();
|
||||
const originalUrl = req.originalUrl || req.url;
|
||||
const method = req.method;
|
||||
|
||||
// 为了捕获响应信息,我们需要拦截res.end
|
||||
const originalEnd = res.end;
|
||||
res.end = function(chunk, encoding) {
|
||||
// 恢复原始的end方法
|
||||
res.end = originalEnd;
|
||||
|
||||
// 计算响应时间
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
// 获取状态码
|
||||
const statusCode = res.statusCode;
|
||||
|
||||
// 记录请求信息
|
||||
const requestInfo = {
|
||||
method,
|
||||
path: originalUrl,
|
||||
statusCode,
|
||||
duration,
|
||||
timestamp: new Date(),
|
||||
userAgent: req.headers['user-agent'],
|
||||
ip: req.ip || req.connection.remoteAddress
|
||||
};
|
||||
|
||||
// 记录到性能监控系统
|
||||
performanceMonitor.recordApiRequest(req, res, startTime);
|
||||
|
||||
// 记录慢响应
|
||||
const slowThreshold = performanceMonitor.getAlertThresholds().api.responseTime;
|
||||
if (duration > slowThreshold) {
|
||||
logger.warn(`慢API响应: ${method} ${originalUrl} - ${duration}ms (阈值: ${slowThreshold}ms)`);
|
||||
}
|
||||
|
||||
// 记录错误响应
|
||||
if (statusCode >= 400) {
|
||||
logger.error(`API错误: ${method} ${originalUrl} - 状态码 ${statusCode}`);
|
||||
}
|
||||
|
||||
// 调用原始的end方法
|
||||
return originalEnd.call(this, chunk, encoding);
|
||||
};
|
||||
|
||||
// 继续处理请求
|
||||
next();
|
||||
}
|
||||
|
||||
/**
|
||||
* 错误处理中间件
|
||||
* 捕获并记录API错误
|
||||
*/
|
||||
function apiErrorMonitor(err, req, res, next) {
|
||||
// 记录错误信息
|
||||
logger.error(`API错误: ${req.method} ${req.originalUrl || req.url}`, {
|
||||
error: err.message,
|
||||
stack: err.stack
|
||||
});
|
||||
|
||||
// 触发错误事件
|
||||
perfEvents.emit('apiError', {
|
||||
method: req.method,
|
||||
path: req.originalUrl || req.url,
|
||||
error: err.message,
|
||||
timestamp: new Date()
|
||||
});
|
||||
|
||||
// 继续错误处理链
|
||||
next(err);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
apiPerformanceMonitor,
|
||||
apiErrorMonitor
|
||||
};
|
||||
Reference in New Issue
Block a user