170 lines
4.5 KiB
JavaScript
170 lines
4.5 KiB
JavaScript
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
|
||
}; |