From 19a8426163099d5040b2f6c7bcbb90590a87cf47 Mon Sep 17 00:00:00 2001 From: liangweihao <734499798@qq.com> Date: Sat, 6 Sep 2025 09:57:59 +0800 Subject: [PATCH] =?UTF-8?q?debug:=20=E6=B7=BB=E5=8A=A0=E8=AF=A6=E7=BB=86?= =?UTF-8?q?=E7=9A=84=E7=99=BB=E5=BD=95=E8=B0=83=E8=AF=95=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在后端login控制器中添加详细的执行步骤日志 - 添加错误捕获和处理,防止未捕获的异常 - 在前端LoginForm中添加详细的错误日志输出 - 在rate limiter中添加详细的限制日志 - 在请求日志中添加POST请求体信息 - 帮助定位401错误的具体原因 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- backend/src/controllers/authController.ts | 20 +++++++++++++++++++- backend/src/index.ts | 13 +++++++++++++ frontend/src/components/LoginForm.vue | 9 ++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/backend/src/controllers/authController.ts b/backend/src/controllers/authController.ts index b132799..1c705e6 100644 --- a/backend/src/controllers/authController.ts +++ b/backend/src/controllers/authController.ts @@ -103,13 +103,18 @@ export const authController = { // 用户登录 async login(req: Request, res: Response) { - const { username, password } = req.body; + try { + const { username, password } = req.body; + + console.log('登录请求:', { username, timestamp: new Date().toISOString() }); // Find user const user = await prisma.user.findUnique({ where: { username } }); + console.log('查找用户结果:', { found: !!user, isActive: user?.isActive, userId: user?.id }); + if (!user) { // 记录登录失败审计日志 await prisma.auditLog.create({ @@ -144,7 +149,10 @@ export const authController = { } // Verify password + console.log('开始验证密码...'); const isValidPassword = await bcrypt.compare(password, user.password); + console.log('密码验证结果:', { isValid: isValidPassword }); + if (!isValidPassword) { // 增加登录失败次数 const loginAttempts = (user.loginAttempts || 0) + 1; @@ -199,17 +207,22 @@ export const authController = { }); // Generate token + console.log('生成token...'); const token = generateToken(user.id); + console.log('Token生成成功:', token.substring(0, 20) + '...'); // Delete existing sessions for this user (optional - for single session per user) + console.log('删除用户现有sessions...'); await prisma.session.deleteMany({ where: { userId: user.id } }); // Create session + console.log('创建新session...'); await createSession(user.id, token, req); // Update last login + console.log('更新最后登录时间...'); await prisma.user.update({ where: { id: user.id }, data: { lastLoginAt: new Date() } @@ -227,6 +240,7 @@ export const authController = { } }); + console.log('登录成功,返回响应...'); return res.json({ message: '登录成功', token, @@ -236,6 +250,10 @@ export const authController = { isAdmin: user.isAdmin, } }); + } catch (error) { + console.error('登录过程中发生错误:', error); + return res.status(500).json({ error: '服务器内部错误' }); + } }, // 用户登出 diff --git a/backend/src/index.ts b/backend/src/index.ts index 68d0556..7d330c6 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -37,6 +37,13 @@ const limiter = rateLimit({ max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS || '100'), // limit each IP to 100 requests per windowMs message: { error: 'Too many requests from this IP, please try again later.' + }, + // 添加详细日志 + handler: (req, res) => { + console.log('Rate limit exceeded for IP:', req.ip, 'Path:', req.path); + res.status(429).json({ + error: 'Too many requests from this IP, please try again later.' + }); } }); app.use('/api/', limiter); @@ -47,6 +54,12 @@ app.use(express.urlencoded({ extended: true })); // Request logging app.use((req, res, next) => { + console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`, { + ip: (req.headers['x-forwarded-for'] as string) || req.socket.remoteAddress, + userAgent: req.get('User-Agent'), + body: req.method === 'POST' ? req.body : undefined + }); + logger.info(`${req.method} ${req.path}`, { ip: (req.headers['x-forwarded-for'] as string) || req.socket.remoteAddress, userAgent: req.get('User-Agent') diff --git a/frontend/src/components/LoginForm.vue b/frontend/src/components/LoginForm.vue index f5b6949..9f72f77 100644 --- a/frontend/src/components/LoginForm.vue +++ b/frontend/src/components/LoginForm.vue @@ -116,7 +116,14 @@ const handleLogin = async () => { router.push('/dashboard') } catch (error: any) { - console.log(error) + console.error('登录失败,详细错误信息:', { + status: error.response?.status, + statusText: error.response?.statusText, + data: error.response?.data, + url: error.config?.url, + method: error.config?.method, + headers: error.config?.headers + }) // 根据不同的错误类型显示不同的错误信息 if (error.response?.status === 401) { const errorMessage = error.response?.data?.error || '用户名或密码错误'