6k6g-v3 / src /middleware /adminAuth.ts
fanyubo
HF Space backend - slow task worker
90647f1
Raw
History Blame Contribute Delete
3.44 kB
/**
* 管理员认证中间件
* 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;
}