- 최고관리자(Supervisor) 전용 2중 보안 잠금 시스템 및 인증 UI 적용 - 데이터베이스 인프라 및 암호화 마스터 키 자가 관리 기능 구축 - 권한 계층(Supervisor > Admin > User) 기반의 메뉴 노출 및 접근 제어 로직 강화 - 시스템 버전 정보 페이지 신규 추가 및 패키지 버전 자동 연동 (v0.2.5) - 사용자 관리 UI 디자인 개선 및 폰트/스타일 일원화
46 lines
1.8 KiB
JavaScript
46 lines
1.8 KiB
JavaScript
const crypto = require('crypto');
|
|
|
|
// Generate a random token
|
|
const generateToken = () => {
|
|
return crypto.randomBytes(24).toString('hex');
|
|
};
|
|
|
|
// Middleware to protect against CSRF
|
|
const csrfProtection = (req, res, next) => {
|
|
// Skip for GET, HEAD, OPTIONS (safe methods)
|
|
if (['GET', 'HEAD', 'OPTIONS'].includes(req.method)) {
|
|
return next();
|
|
}
|
|
|
|
// Skip for Login endpoint
|
|
if (req.path === '/api/login' || req.path === '/api/auth/login') {
|
|
return next();
|
|
}
|
|
|
|
// Get token from header
|
|
const tokenFromHeader = req.headers['x-csrf-token'];
|
|
|
|
// Get token from session
|
|
const tokenFromSession = req.session.csrfToken;
|
|
|
|
if (!tokenFromSession || !tokenFromHeader || tokenFromSession !== tokenFromHeader) {
|
|
console.error('🔒 [CSRF Security] Token Mismatch Detected');
|
|
console.error(`- Path: ${req.path}`);
|
|
console.error(`- Session ID: ${req.sessionID ? req.sessionID.substring(0, 8) + '...' : 'NONE'}`);
|
|
console.error(`- Session User: ${req.session?.user?.id || 'GUEST'}`);
|
|
console.error(`- Session MaxAge: ${req.session?.cookie?.maxAge / 1000 / 60} min`);
|
|
console.error(`- Token in Session: ${tokenFromSession ? 'EXISTS (' + tokenFromSession.substring(0, 5) + '...)' : 'MISSING'}`);
|
|
console.error(`- Token in Header: ${tokenFromHeader ? 'EXISTS (' + tokenFromHeader.substring(0, 5) + '...)' : 'MISSING'}`);
|
|
|
|
return res.status(403).json({
|
|
success: false,
|
|
message: 'Invalid CSRF Token',
|
|
error: '세션 보안 토큰(CSRF)이 일치하지 않습니다. 보안 정책에 따라 요청이 거부되었습니다. 다시 로그인하거나 새로고침 후 시도해 주세요.'
|
|
});
|
|
}
|
|
|
|
next();
|
|
};
|
|
|
|
module.exports = { generateToken, csrfProtection };
|