smart_ims/server/middleware/csrfMiddleware.js

45 lines
1.7 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(`- 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 };