const db = require('../config/database'); /** * 认证中间件 - 检查用户是否已登录 */ const requireAuth = (req, res, next) => { if (!req.session.user) { return res.status(401).json({ success: false, message: '请先登录' }); } next(); }; /** * 角色权限中间件 - 检查用户是否具有指定角色 * @param {Array} allowedRoles - 允许的角色数组 */ const requireRole = (allowedRoles) => { return (req, res, next) => { if (!req.session.user) { return res.status(401).json({ success: false, message: '请先登录' }); } const userRole = req.session.user.role; if (!allowedRoles.includes(userRole)) { return res.status(403).json({ success: false, message: '权限不足' }); } next(); }; }; /** * 获取当前用户ID */ const getCurrentUserId = (req) => { return req.session.user ? req.session.user.id : null; }; /** * 获取当前用户角色 */ const getCurrentUserRole = (req) => { return req.session.user ? req.session.user.role : null; }; /** * 检查是否是自己的数据(学生只能访问自己的数据) */ const checkOwnership = async (req, res, next) => { try { const userId = getCurrentUserId(req); const userRole = getCurrentUserRole(req); // 管理员和教师可以访问所有数据 if (userRole === 'admin' || userRole === 'teacher') { return next(); } // 学生只能访问自己的数据 if (userRole === 'student') { const studentId = req.params.studentId || req.body.studentId; // 检查学生ID是否属于当前用户 const [students] = await db.execute( 'SELECT id FROM students WHERE user_id = ?', [userId] ); if (students.length === 0) { return res.status(403).json({ success: false, message: '未找到学生信息' }); } const userStudentId = students[0].id; // 如果请求中没有指定学生ID,默认使用当前用户的学生ID if (!studentId) { req.studentId = userStudentId; return next(); } // 检查请求的学生ID是否与当前用户的学生ID匹配 if (parseInt(studentId) !== userStudentId) { return res.status(403).json({ success: false, message: '无权访问其他学生的数据' }); } req.studentId = userStudentId; return next(); } // 其他角色无权访问 return res.status(403).json({ success: false, message: '权限不足' }); } catch (error) { console.error('所有权检查错误:', error); res.status(500).json({ success: false, message: '服务器错误' }); } }; /** * 输入验证中间件 */ const validateInput = (schema) => { return (req, res, next) => { const { error } = schema.validate(req.body); if (error) { return res.status(400).json({ success: false, message: error.details[0].message }); } next(); }; }; /** * 日志记录中间件 */ const logOperation = (operation) => { return async (req, res, next) => { try { const userId = getCurrentUserId(req); const userRole = getCurrentUserRole(req); const ip = req.ip || req.connection.remoteAddress; // 记录操作日志 await db.execute( 'INSERT INTO operation_logs (user_id, operation, ip_address, user_role) VALUES (?, ?, ?, ?)', [userId, operation, ip, userRole] ); next(); } catch (error) { console.error('日志记录错误:', error); // 日志记录失败不影响主要操作 next(); } }; }; module.exports = { requireAuth, requireRole, getCurrentUserId, getCurrentUserRole, checkOwnership, validateInput, logOperation };