184 lines
5.4 KiB
JavaScript
184 lines
5.4 KiB
JavaScript
const express = require('express');
|
|
const cors = require('cors');
|
|
const bodyParser = require('body-parser');
|
|
const path = require('path');
|
|
// Oracle DB 연결
|
|
const dbConnection = require('./database/connection');
|
|
const { createTable } = require('./database/queries');
|
|
const { createAuthTables } = require('./database/auth-queries');
|
|
const { createUserTable } = require('./database/user-queries');
|
|
const { createApiLogTable } = require('./database/log-queries');
|
|
const { skipLogging } = require('./middleware/logger');
|
|
const apiRoutes = require('./routes/api');
|
|
const authRoutes = require('./routes/auth');
|
|
const usersRoutes = require('./routes/users');
|
|
const logsRoutes = require('./routes/logs');
|
|
|
|
const app = express();
|
|
const PORT = 5577;
|
|
|
|
// 미들웨어 설정
|
|
app.use(cors({
|
|
origin: [
|
|
'http://localhost:5577',
|
|
'http://127.0.0.1:5577',
|
|
'http://39.117.244.52:5577',
|
|
'https://39.117.244.52:5577'
|
|
],
|
|
credentials: true,
|
|
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
allowedHeaders: ['Content-Type', 'Authorization', 'X-API-Key', 'X-Requested-With'],
|
|
exposedHeaders: ['Content-Length', 'X-Foo', 'X-Bar']
|
|
}));
|
|
app.use(bodyParser.json({ limit: '50mb' }));
|
|
app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' }));
|
|
|
|
// OPTIONS 요청 처리 (CORS preflight)
|
|
app.options('*', (req, res) => {
|
|
const origin = req.headers.origin;
|
|
const allowedOrigins = [
|
|
'http://localhost:5577',
|
|
'http://127.0.0.1:5577',
|
|
'http://39.117.244.52:5577',
|
|
'https://39.117.244.52:5577'
|
|
];
|
|
|
|
if (allowedOrigins.includes(origin)) {
|
|
res.header('Access-Control-Allow-Origin', origin);
|
|
} else {
|
|
res.header('Access-Control-Allow-Origin', 'http://39.117.244.52:5577');
|
|
}
|
|
|
|
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-API-Key, X-Requested-With');
|
|
res.header('Access-Control-Allow-Credentials', 'true');
|
|
res.sendStatus(200);
|
|
});
|
|
|
|
// 정적 파일 서빙 (개발 환경에서 캐시 비활성화)
|
|
app.use(express.static(path.join(__dirname, 'public'), {
|
|
etag: false,
|
|
lastModified: false,
|
|
setHeaders: (res, path) => {
|
|
// 개발 환경에서 캐시 비활성화
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
res.setHeader('Pragma', 'no-cache');
|
|
res.setHeader('Expires', '0');
|
|
}
|
|
}
|
|
}));
|
|
|
|
// API 로깅 미들웨어 (정적 파일, 헬스체크, 로그 조회는 제외)
|
|
app.use(skipLogging([
|
|
'/favicon.ico',
|
|
'/api/health',
|
|
'/logs/api-logs',
|
|
'/logs/api-logs/stats',
|
|
/^\/css\//,
|
|
/^\/js\//,
|
|
/^\/images\//,
|
|
/^\/fonts\//,
|
|
/^\/auth\// // 인증 관련 경로도 제외
|
|
]));
|
|
|
|
// 요청 로깅 미들웨어
|
|
app.use((req, res, next) => {
|
|
console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
|
|
next();
|
|
});
|
|
|
|
// API 라우트 설정
|
|
app.use('/api', apiRoutes);
|
|
app.use('/api/users', usersRoutes);
|
|
app.use('/auth', authRoutes);
|
|
app.use('/logs', logsRoutes);
|
|
|
|
// 기본 라우트 - 웹 UI 서빙
|
|
app.get('/', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
|
});
|
|
|
|
// API 정보 엔드포인트
|
|
app.get('/info', (req, res) => {
|
|
res.json({
|
|
message: 'REST API 서버에 오신 것을 환영합니다!',
|
|
version: '1.0.0',
|
|
webUI: 'http://localhost:5577',
|
|
endpoints: {
|
|
// 인증 API
|
|
login: 'POST /auth/login',
|
|
register: 'POST /auth/register',
|
|
createApiKey: 'POST /auth/api-keys',
|
|
// 데이터 API
|
|
health: 'GET /api/health',
|
|
getAllData: 'GET /api/data',
|
|
getDataById: 'GET /api/data/:id',
|
|
createData: 'POST /api/data',
|
|
updateData: 'PUT /api/data/:id',
|
|
deleteData: 'DELETE /api/data/:id'
|
|
}
|
|
});
|
|
});
|
|
|
|
// 404 에러 핸들러
|
|
app.use('*', (req, res) => {
|
|
res.status(404).json({
|
|
success: false,
|
|
message: '요청한 엔드포인트를 찾을 수 없습니다'
|
|
});
|
|
});
|
|
|
|
// 에러 핸들러
|
|
app.use((err, req, res, next) => {
|
|
console.error('서버 에러:', err);
|
|
res.status(500).json({
|
|
success: false,
|
|
message: '내부 서버 오류가 발생했습니다',
|
|
error: process.env.NODE_ENV === 'development' ? err.message : undefined
|
|
});
|
|
});
|
|
|
|
// 서버 시작
|
|
async function startServer() {
|
|
try {
|
|
// Oracle DB 연결 풀 초기화
|
|
await dbConnection.initializePool();
|
|
|
|
// 테이블 생성 (존재하지 않는 경우)
|
|
await createTable();
|
|
await createAuthTables();
|
|
await createUserTable();
|
|
await createApiLogTable();
|
|
|
|
// 서버 시작
|
|
app.listen(PORT, () => {
|
|
console.log(`\n=================================`);
|
|
console.log(`🚀 REST API 서버가 시작되었습니다!`);
|
|
console.log(`📍 포트: ${PORT}`);
|
|
console.log(`🌐 URL: http://localhost:${PORT}`);
|
|
console.log(`📊 API 문서: http://localhost:${PORT}/api/health`);
|
|
console.log(`=================================\n`);
|
|
});
|
|
} catch (error) {
|
|
console.error('서버 시작 실패:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// 서버 종료 처리
|
|
process.on('SIGINT', async () => {
|
|
console.log('\n서버를 종료합니다...');
|
|
await dbConnection.closePool();
|
|
process.exit(0);
|
|
});
|
|
|
|
process.on('SIGTERM', async () => {
|
|
console.log('\n서버를 종료합니다...');
|
|
await dbConnection.closePool();
|
|
process.exit(0);
|
|
});
|
|
|
|
// 서버 시작
|
|
startServer();
|