From 35aa4a840e735c1b02c2f7798919ea546f2d68ed Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Mon, 26 Jan 2026 12:42:00 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=20=EC=8B=9C=20500=20=EC=97=90=EB=9F=AC=20=E2=86=92=20?= =?UTF-8?q?401=20=EC=97=90=EB=9F=AC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 문제 - 로그인 실패 시 401 에러를 반환해야 하는데 500 에러 반환 - 원인: ApiError(utils/errorHandler.js)와 AppError(utils/errors.js) 클래스 불일치 - errorHandler 미들웨어가 ApiError를 인식하지 못해 500으로 변환 ## 수정사항 1. authController.js: - ApiError 대신 AuthenticationError, ValidationError 사용 - 로그인 실패 → AuthenticationError 던짐 (401) - 유효성 검증 실패 → ValidationError 던짐 (400) 2. db/connection.js 추가: - TBM 모델의 콜백 방식 DB 쿼리 지원 - dbPool을 래핑하여 레거시 코드 호환 3. routes.js: - TBM 라우트 임시 비활성화 (db/connection 볼륨 마운트 문제) - Docker 볼륨 재설정 후 재활성화 예정 ## 테스트 결과 ```bash # Before: 500 Internal Server Error # After: 401 Unauthorized curl -X POST http://localhost:20005/api/auth/login \ -d '{"username":"wrong","password":"wrong"}' # Response: { "success": false, "error": { "message": "아이디 또는 비밀번호가 올바르지 않습니다.", "code": "AUTHENTICATION_ERROR" // ← 정상! } } ``` ## TODO - [ ] Docker 볼륨 설정에 db 디렉토리 전체 추가 - [ ] TBM 라우트 재활성화 - [ ] 중복 에러 처리 시스템 통합 (ApiError 제거) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- api.hyungi.net/config/routes.js | 4 ++-- api.hyungi.net/controllers/authController.js | 7 ++++--- api.hyungi.net/db/connection.js | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 api.hyungi.net/db/connection.js diff --git a/api.hyungi.net/config/routes.js b/api.hyungi.net/config/routes.js index 9d233ed..f5223c2 100644 --- a/api.hyungi.net/config/routes.js +++ b/api.hyungi.net/config/routes.js @@ -40,7 +40,7 @@ function setupRoutes(app) { const attendanceRoutes = require('../routes/attendanceRoutes'); const monthlyStatusRoutes = require('../routes/monthlyStatusRoutes'); const pageAccessRoutes = require('../routes/pageAccessRoutes'); - const tbmRoutes = require('../routes/tbmRoutes'); + // const tbmRoutes = require('../routes/tbmRoutes'); // 임시 비활성화 - db/connection 문제 // Rate Limiters 설정 const rateLimit = require('express-rate-limit'); @@ -128,7 +128,7 @@ function setupRoutes(app) { app.use('/api/tools', toolsRoute); app.use('/api/users', userRoutes); app.use('/api', pageAccessRoutes); // 페이지 접근 권한 관리 - app.use('/api/tbm', tbmRoutes); // TBM 시스템 + // app.use('/api/tbm', tbmRoutes); // TBM 시스템 - 임시 비활성화 app.use('/api', uploadBgRoutes); // Swagger API 문서 diff --git a/api.hyungi.net/controllers/authController.js b/api.hyungi.net/controllers/authController.js index bf9e598..adb2047 100644 --- a/api.hyungi.net/controllers/authController.js +++ b/api.hyungi.net/controllers/authController.js @@ -2,7 +2,8 @@ const { getDb } = require('../dbPool'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const authService = require('../services/auth.service'); -const { ApiError, asyncHandler } = require('../utils/errorHandler'); +const { asyncHandler } = require('../utils/errorHandler'); +const { AuthenticationError, ValidationError } = require('../utils/errors'); const { validateSchema, schemas } = require('../utils/validator'); const login = asyncHandler(async (req, res) => { @@ -12,13 +13,13 @@ const login = asyncHandler(async (req, res) => { // 유효성 검사 if (!username || !password) { - throw new ApiError('사용자명과 비밀번호를 입력해주세요.', 400); + throw new ValidationError('사용자명과 비밀번호를 입력해주세요.'); } const result = await authService.loginService(username, password, ipAddress, userAgent); if (!result.success) { - throw new ApiError(result.error, result.status || 400); + throw new AuthenticationError(result.error); } // 로그인 성공 후, 메인 대시보드로 리다이렉트 diff --git a/api.hyungi.net/db/connection.js b/api.hyungi.net/db/connection.js new file mode 100644 index 0000000..9ad0597 --- /dev/null +++ b/api.hyungi.net/db/connection.js @@ -0,0 +1,17 @@ +// db/connection.js - 레거시 콜백 방식 DB 래퍼 +const { getDb } = require('../dbPool'); + +// 콜백 방식 쿼리 래퍼 +const query = async (sql, params, callback) => { + try { + const db = await getDb(); + const [results] = await db.query(sql, params); + callback(null, results); + } catch (error) { + callback(error); + } +}; + +module.exports = { + query +};