refactor: Phase 3.3 - 통합 인증/인가 미들웨어 시스템 구축
주요 변경사항:
1. middlewares/auth.js 신규 생성 (355 lines)
* 4개 핵심 미들웨어 통합:
- requireAuth: JWT 토큰 검증
- requireRole(...roles): 특정 역할 체크
- requireMinLevel(level): 계층적 권한 레벨 체크
- requireOwnerOrAdmin(options): 소유자/관리자 체크
* 커스텀 에러 클래스 적용:
- AuthenticationError (401)
- ForbiddenError (403)
* 구조화된 로깅 시스템 통합
* 레거시 호환성 별칭 제공:
- verifyToken = requireAuth
- requireAdmin = requireRole('admin', 'system')
- requireSystem = requireRole('system')
* ACCESS_LEVELS 상수 정의 및 export
2. 라우터 업데이트 (새로운 미들웨어 적용)
* routes/workReportAnalysisRoutes.js
- authMiddleware → auth로 변경
- requireAdmin → requireRole('admin', 'system')
* routes/systemRoutes.js
- 커스텀 requireSystemAccess 제거
- requireRole('system') 사용
- 14줄 코드 감소 (298 → 284 lines)
* routes/auth.js
- utils/access의 requireAccess 제거
- requireAuth + requireRole 조합 사용
3. 레거시 호환성 래퍼 (하위 호환성 유지)
* middlewares/authMiddleware.js (89 → 37 lines, 58% 감소)
- auth.js의 래퍼로 변경
- @deprecated 태그 추가
- 기존 22개 파일 호환성 유지
* middlewares/accessMiddleware.js (33 → 30 lines)
- requireMinLevel 래퍼로 변경
- @deprecated 태그 및 마이그레이션 가이드 추가
* utils/access.js
- requireAccess 레거시 함수 추가 (하위 호환성)
- 유틸리티 함수들은 그대로 유지
기술적 개선사항:
- 중복 코드 제거: 4개 파일에 분산된 인증 로직 통합
- 일관된 에러 처리: 커스텀 에러 클래스 사용
- 상세한 로깅: 인증/인가 실패 원인 추적 가능
- 보안 강화: TokenExpiredError, JsonWebTokenError 세분화 처리
- 확장성: 새로운 권한 체크 패턴 쉽게 추가 가능
- JSDoc 문서화: 모든 함수에 상세한 사용 예제 포함
통합 전후 비교:
- 미들웨어 파일: 4개 → 1개 (통합) + 3개 (래퍼)
- 중복 코드: ~150 lines → 0 lines
- 일관성: 4가지 다른 패턴 → 1가지 통합 패턴
레거시 호환성:
- 기존 22개 라우터 파일 중 19개는 수정 없이 동작
- 3개 라우터만 새로운 패턴으로 업데이트 (예시용)
- verifyToken, requireAdmin, requireSystem 별칭 제공
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,89 +1,36 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
exports.verifyToken = (req, res, next) => {
|
||||
try {
|
||||
const authHeader = req.headers['authorization'];
|
||||
if (!authHeader) {
|
||||
return res.status(401).json({ error: '토큰 없음' });
|
||||
}
|
||||
|
||||
const token = authHeader.split(' ')[1];
|
||||
if (!token) {
|
||||
return res.status(401).json({ error: '토큰 누락' });
|
||||
}
|
||||
|
||||
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
||||
req.user = decoded;
|
||||
next(); // ✅ 반드시 next 호출
|
||||
} catch (err) {
|
||||
console.error('[verifyToken 오류]', err.message);
|
||||
return res.status(403).json({ error: '토큰 검증 실패', detail: err.message });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Admin 등급 이상 권한 체크 미들웨어
|
||||
* @deprecated 이 파일은 하위 호환성을 위해 유지됩니다.
|
||||
* 새로운 코드에서는 './auth'를 직접 import하세요.
|
||||
*
|
||||
* @example
|
||||
* // 이전 방식 (deprecated)
|
||||
* const { verifyToken, requireAdmin } = require('../middlewares/authMiddleware');
|
||||
*
|
||||
* // 새로운 방식 (권장)
|
||||
* const { requireAuth, requireRole } = require('../middlewares/auth');
|
||||
*/
|
||||
exports.requireAdmin = (req, res, next) => {
|
||||
try {
|
||||
if (!req.user) {
|
||||
return res.status(401).json({
|
||||
error: '인증 필요',
|
||||
message: '먼저 로그인해주세요.'
|
||||
});
|
||||
}
|
||||
|
||||
const userRole = req.user.role;
|
||||
const adminRoles = ['admin', 'system'];
|
||||
|
||||
if (!adminRoles.includes(userRole)) {
|
||||
return res.status(403).json({
|
||||
error: '권한 부족',
|
||||
message: '관리자 권한이 필요합니다.',
|
||||
required: 'admin 또는 system',
|
||||
current: userRole
|
||||
});
|
||||
}
|
||||
const {
|
||||
requireAuth,
|
||||
requireRole,
|
||||
requireMinLevel,
|
||||
requireOwnerOrAdmin,
|
||||
verifyToken,
|
||||
requireAdmin,
|
||||
requireSystem,
|
||||
ACCESS_LEVELS
|
||||
} = require('./auth');
|
||||
|
||||
console.log(`✅ Admin 권한 확인: ${req.user.username} (${userRole})`);
|
||||
next();
|
||||
} catch (err) {
|
||||
console.error('[requireAdmin 오류]', err.message);
|
||||
return res.status(500).json({
|
||||
error: '권한 확인 중 오류 발생',
|
||||
detail: err.message
|
||||
});
|
||||
}
|
||||
module.exports = {
|
||||
// 레거시 별칭 (하위 호환성)
|
||||
verifyToken,
|
||||
requireAdmin,
|
||||
requireSystem,
|
||||
|
||||
// 새로운 API (권장)
|
||||
requireAuth,
|
||||
requireRole,
|
||||
requireMinLevel,
|
||||
requireOwnerOrAdmin,
|
||||
ACCESS_LEVELS
|
||||
};
|
||||
|
||||
/**
|
||||
* System 등급 권한 체크 미들웨어
|
||||
*/
|
||||
exports.requireSystem = (req, res, next) => {
|
||||
try {
|
||||
if (!req.user) {
|
||||
return res.status(401).json({
|
||||
error: '인증 필요',
|
||||
message: '먼저 로그인해주세요.'
|
||||
});
|
||||
}
|
||||
|
||||
if (req.user.role !== 'system') {
|
||||
return res.status(403).json({
|
||||
error: '권한 부족',
|
||||
message: '시스템 관리자 권한이 필요합니다.',
|
||||
required: 'system',
|
||||
current: req.user.role
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`✅ System 권한 확인: ${req.user.username}`);
|
||||
next();
|
||||
} catch (err) {
|
||||
console.error('[requireSystem 오류]', err.message);
|
||||
return res.status(500).json({
|
||||
error: '권한 확인 중 오류 발생',
|
||||
detail: err.message
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user