first commit

This commit is contained in:
祀梦
2025-12-21 21:50:37 +08:00
commit 352698044b
30 changed files with 9893 additions and 0 deletions

170
backend/middleware/auth.js Normal file
View File

@@ -0,0 +1,170 @@
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
};