const jwt = require('jsonwebtoken'); const User = require('../models/User'); /** * Authentication middleware * Verifies JWT token and attaches user to request */ const authenticateToken = async (req, res, next) => { try { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN if (!token) { return res.status(401).json({ success: false, message: 'Access token required' }); } const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findById(decoded.userId).select('-password'); if (!user || !user.isActive) { return res.status(401).json({ success: false, message: 'Invalid or inactive user' }); } req.user = user; next(); } catch (error) { console.error('Token verification error:', error); return res.status(403).json({ success: false, message: 'Invalid token' }); } }; /** * Session-based authentication middleware * For web pages using sessions */ const authenticateSession = async (req, res, next) => { try { if (!req.session.userId) { req.flash('error', '로그인이 필요합니다.'); return res.redirect('/auth/login'); } const user = await User.findById(req.session.userId).select('-password'); if (!user || !user.isActive) { req.session.destroy(); req.flash('error', '유효하지 않은 사용자입니다.'); return res.redirect('/auth/login'); } req.user = user; res.locals.user = user; next(); } catch (error) { console.error('Session authentication error:', error); req.session.destroy(); req.flash('error', '인증 오류가 발생했습니다.'); return res.redirect('/auth/login'); } }; /** * Admin role middleware * Requires user to be authenticated and have admin role */ const requireAdmin = (req, res, next) => { if (!req.user) { return res.status(401).json({ success: false, message: 'Authentication required' }); } if (req.user.role !== 'admin') { return res.status(403).json({ success: false, message: 'Admin access required' }); } next(); }; /** * Admin session middleware for web pages */ const requireAdminSession = (req, res, next) => { if (!req.user) { req.flash('error', '로그인이 필요합니다.'); return res.redirect('/auth/login'); } if (req.user.role !== 'admin') { req.flash('error', '관리자 권한이 필요합니다.'); return res.redirect('/'); } next(); }; /** * Optional authentication middleware * Attaches user if token exists but doesn't require it */ const optionalAuth = async (req, res, next) => { try { // Check session first if (req.session.userId) { const user = await User.findById(req.session.userId).select('-password'); if (user && user.isActive) { req.user = user; res.locals.user = user; } } // Check JWT token if no session if (!req.user) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (token) { const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findById(decoded.userId).select('-password'); if (user && user.isActive) { req.user = user; res.locals.user = user; } } } next(); } catch (error) { // Continue without authentication if token is invalid next(); } }; module.exports = { authenticateToken, authenticateSession, requireAdmin, requireAdminSession, optionalAuth };