Spaces:
Sleeping
Sleeping
| /** | |
| * 管理员认证中间件 | |
| * Session/Cookie 保护 /dashboard 和 /api/stats | |
| */ | |
| import cookieParser from 'cookie-parser'; | |
| // Session 存储(生产环境应使用 Redis) | |
| const SESSIONS: Map<string, { user: string; expires: number }> = new Map(); | |
| // Session 有效期 24 小时 | |
| const SESSION_EXPIRY = 24 * 60 * 60 * 1000; | |
| // 环境变量凭证 | |
| const ADMIN_USER = process.env.ADMIN_USER || 'admin'; | |
| const ADMIN_PASS = process.env.ADMIN_PASS || ''; | |
| // Session Secret(用于签名) | |
| const SESSION_SECRET = process.env.SESSION_SECRET || 'default-secret-change-me'; | |
| /** | |
| * 初始化 Cookie Parser | |
| */ | |
| export function initCookieParser() { | |
| return cookieParser(); | |
| } | |
| /** | |
| * 生成 Session Token | |
| */ | |
| function generateSessionToken(): string { | |
| const randomBytes = new Uint8Array(32); | |
| crypto.getRandomValues(randomBytes); | |
| return Array.from(randomBytes).map(b => b.toString(16).padStart(2, '0')).join(''); | |
| } | |
| /** | |
| * 验证凭证并创建 Session | |
| */ | |
| export function createSession(user: string, pass: string): { success: boolean; token?: string; error?: string } { | |
| // 检查凭证 | |
| if (user !== ADMIN_USER || pass !== ADMIN_PASS) { | |
| return { success: false, error: 'Invalid credentials' }; | |
| } | |
| // 检查是否配置了密码 | |
| if (!ADMIN_PASS) { | |
| return { success: false, error: 'Admin password not configured' }; | |
| } | |
| // 创建 Session | |
| const token = generateSessionToken(); | |
| const expires = Date.now() + SESSION_EXPIRY; | |
| SESSIONS.set(token, { user, expires }); | |
| console.log('[Auth] Session created for user:', user); | |
| return { success: true, token }; | |
| } | |
| /** | |
| * 验证 Session Token | |
| */ | |
| export function validateSession(token: string): { valid: boolean; user?: string } { | |
| const session = SESSIONS.get(token); | |
| if (!session) { | |
| return { valid: false }; | |
| } | |
| if (session.expires < Date.now()) { | |
| SESSIONS.delete(token); | |
| return { valid: false }; | |
| } | |
| return { valid: true, user: session.user }; | |
| } | |
| /** | |
| * 删除 Session(注销) | |
| */ | |
| export function destroySession(token: string): void { | |
| SESSIONS.delete(token); | |
| console.log('[Auth] Session destroyed'); | |
| } | |
| /** | |
| * 路由保护中间件 | |
| * 检查 Session Cookie,未登录重定向到 /login | |
| */ | |
| export function requireAdmin(req: any, res: any, next: any): void { | |
| const session = req.cookies?.admin_session; | |
| if (!session) { | |
| return res.redirect('/login'); | |
| } | |
| const validation = validateSession(session); | |
| if (!validation.valid) { | |
| return res.redirect('/login'); | |
| } | |
| // 设置用户信息到请求对象 | |
| req.user = validation.user; | |
| next(); | |
| } | |
| /** | |
| * API 保护中间件 | |
| * 检查 Session,返回 401 JSON 响应 | |
| */ | |
| export function requireAdminApi(req: any, res: any, next: any): void { | |
| const session = req.cookies?.admin_session; | |
| if (!session) { | |
| return res.status(401).json({ error: 'Unauthorized' }); | |
| } | |
| const validation = validateSession(session); | |
| if (!validation.valid) { | |
| return res.status(401).json({ error: 'Session expired' }); | |
| } | |
| req.user = validation.user; | |
| next(); | |
| } | |
| /** | |
| * 清理过期 Session(可定期调用) | |
| */ | |
| export function cleanupExpiredSessions(): number { | |
| const now = Date.now(); | |
| let cleaned = 0; | |
| for (const [token, session] of SESSIONS.entries()) { | |
| if (session.expires < now) { | |
| SESSIONS.delete(token); | |
| cleaned++; | |
| } | |
| } | |
| if (cleaned > 0) { | |
| console.log('[Auth] Cleaned', cleaned, 'expired sessions'); | |
| } | |
| return cleaned; | |
| } |