import { eq } from 'drizzle-orm' import { useDB, schema } from '../../utils/db.js' import { hashPassword, createSession } from '../../utils/auth.js' // 简单的登录频率限制 const loginAttempts = new Map() const MAX_ATTEMPTS = 5 const LOCK_TIME = 15 * 60 * 1000 // 15 分钟 export default defineEventHandler(async (event) => { const ip = getRequestIP(event, { xForwardedFor: true }) ?? 'unknown' // 检查频率限制 const record = loginAttempts.get(ip) if (record && record.count >= MAX_ATTEMPTS && Date.now() - record.firstAt < LOCK_TIME) { const waitMin = Math.ceil((LOCK_TIME - (Date.now() - record.firstAt)) / 60000) throw createError({ statusCode: 429, message: `登录尝试过多,请 ${waitMin} 分钟后再试` }) } const body = await readBody(event) const { username, password } = body || {} if (!username || !password) { throw createError({ statusCode: 422, message: '请输入用户名和密码' }) } const db = useDB() const user = db .select() .from(schema.adminUsers) .where(eq(schema.adminUsers.username, username)) .get() if (!user || user.passwordHash !== hashPassword(password)) { // 记录失败次数 const current = loginAttempts.get(ip) || { count: 0, firstAt: Date.now() } if (Date.now() - current.firstAt > LOCK_TIME) { loginAttempts.set(ip, { count: 1, firstAt: Date.now() }) } else { current.count++ loginAttempts.set(ip, current) } throw createError({ statusCode: 401, message: '用户名或密码错误' }) } // 登录成功,清除计数 loginAttempts.delete(ip) const token = createSession(user.id) return { success: true, token, username: user.username } })