clash-linux's picture
Upload 27 files
146bdba verified
import { createLogger } from '../utils/logger.js';
import { config } from '../config/index.js';
const logger = createLogger('AuthMiddleware');
// 存储有效的会话令牌(实际生产环境中应使用Redis或其他持久化存储)
const sessionTokens = new Map();
/**
* 认证中间件
* 验证请求的Bearer token
*/
export function authenticate(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
logger.warning(`认证失败: 缺少Bearer token - IP: ${req.ip}`);
return res.status(401).json({
error: {
message: "Authentication required. Please provide a valid Bearer token.",
type: "authentication_error"
}
});
}
const token = authHeader.split(' ')[1];
// 首先检查是否是管理员会话令牌
if (sessionTokens.has(token)) {
const session = sessionTokens.get(token);
// 检查会话是否过期(24小时)
if (new Date().getTime() - session.timestamp < 24 * 60 * 60 * 1000) {
logger.debug(`认证成功(管理员会话) - IP: ${req.ip}`);
req.user = session.user;
return next();
} else {
// 会话过期,删除令牌
sessionTokens.delete(token);
}
}
// 检查是否是API令牌
if (token !== config.server.authToken) {
logger.warning(`认证失败: 无效的token - IP: ${req.ip}`);
return res.status(401).json({
error: {
message: "Invalid authentication credentials",
type: "authentication_error"
}
});
}
logger.debug(`认证成功(API令牌) - IP: ${req.ip}`);
next();
}
/**
* 添加会话令牌
*/
export function addSessionToken(token, user) {
sessionTokens.set(token, {
user,
timestamp: new Date().getTime()
});
}
/**
* 清理过期的会话令牌
*/
setInterval(() => {
const now = new Date().getTime();
for (const [token, session] of sessionTokens.entries()) {
if (now - session.timestamp > 24 * 60 * 60 * 1000) {
sessionTokens.delete(token);
}
}
}, 60 * 60 * 1000); // 每小时清理一次
/**
* 请求日志中间件
* 记录所有请求的详细信息
*/
export function requestLogger(req, res, next) {
const start = Date.now();
// 保存原始的 end 方法
const originalEnd = res.end;
// 重写 end 方法以记录请求完成时间
res.end = function(...args) {
const duration = Date.now() - start;
logger.request(req.method, req.path, res.statusCode, duration);
return originalEnd.apply(this, args);
};
next();
}
/**
* 错误处理中间件
* 统一处理所有未捕获的错误
*/
export function errorHandler(err, req, res, next) {
logger.error(`未处理的错误: ${err.message}`, err);
// 如果响应已经发送,则交给默认错误处理器
if (res.headersSent) {
return next(err);
}
// 发送错误响应
res.status(500).json({
error: {
message: process.env.NODE_ENV === 'production'
? 'Internal server error'
: err.message,
type: 'server_error'
}
});
}
/**
* 请求体大小限制中间件配置
*/
export const requestLimits = {
json: { limit: '50mb' },
urlencoded: { extended: true, limit: '50mb' }
};