first commit
This commit is contained in:
170
backend/middleware/auth.js
Normal file
170
backend/middleware/auth.js
Normal 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
|
||||
};
|
||||
Reference in New Issue
Block a user