authn_z
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
\section{Middleware}
|
||||
|
||||
\begin{frame}[shrink=15]{Mi az a middleware?}
|
||||
\begin{block}{Definíció}
|
||||
Függvény HTTP kérés-válasz között, hozzáfér \texttt{req}, \texttt{res}, \texttt{next}-hez.
|
||||
\end{block}
|
||||
\begin{itemize}
|
||||
\item Láncolható
|
||||
\item Kérés előfeldolgozás, válasz utófeldolgozás
|
||||
\item Kérés megszakítható
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[shrink=15]{Middleware működése}
|
||||
\begin{center}
|
||||
\begin{tikzpicture}[node distance=1.4cm, auto]
|
||||
\node (browser) [rectangle, draw, text width=1.5cm, text centered] {Browser};
|
||||
\node (mw1) [rectangle, draw, right of=browser, xshift=1cm, text width=2cm, text centered] {MW 1\\Logger};
|
||||
\node (mw2) [rectangle, draw, right of=mw1, xshift=1.5cm, text width=2cm, text centered] {MW 2\\Auth};
|
||||
\node (route) [rectangle, draw, right of=mw2, xshift=1.5cm, text width=1.5cm, text centered] {Route};
|
||||
|
||||
\draw[->, thick] (browser) -- node[above] {Req} (mw1);
|
||||
\draw[->, thick] (mw1) -- node[above] {\tiny next()} (mw2);
|
||||
\draw[->, thick] (mw2) -- node[above] {\tiny next()} (route);
|
||||
\draw[->, thick, dashed] (route) -- node[below] {Res} (browser);
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
\begin{alertblock}{Fontos}
|
||||
\texttt{next()} nélkül kérés megáll!
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[shrink=15]{Middleware típusok}
|
||||
\begin{enumerate}
|
||||
\item \textbf{Application-level}: \texttt{app.use()}
|
||||
\item \textbf{Router-level}: \texttt{router.use()}
|
||||
\item \textbf{Error-handling}: \texttt{(err, req, res, next)}
|
||||
\item \textbf{Built-in}: \texttt{express.json()}, \texttt{express.static()}
|
||||
\item \textbf{Third-party}: \texttt{cors}, \texttt{helmet}, \texttt{morgan}
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile,shrink=20]{Logger middleware}
|
||||
\begin{verbatim}
|
||||
const logger = (req, res, next) => {
|
||||
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
|
||||
next();
|
||||
};
|
||||
|
||||
app.use(logger);
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.json({ msg: 'Hello' });
|
||||
});
|
||||
|
||||
// Kimenet:
|
||||
// [2026-02-24T10:30:15.000Z] GET /
|
||||
\end{verbatim}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile,shrink=20]{Request timing middleware}
|
||||
\begin{verbatim}
|
||||
const timer = (req, res, next) => {
|
||||
req.startTime = Date.now();
|
||||
res.on('finish', () => {
|
||||
const duration = Date.now() - req.startTime;
|
||||
console.log(`${req.method} ${req.url} - ${duration}ms`);
|
||||
});
|
||||
next();
|
||||
};
|
||||
|
||||
app.use(timer);
|
||||
|
||||
// GET /api/users - 145ms
|
||||
\end{verbatim}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile,shrink=20]{Validation middleware}
|
||||
\begin{verbatim}
|
||||
const validateEmail = (req, res, next) => {
|
||||
const { email } = req.body;
|
||||
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
|
||||
if (!email || !re.test(email)) {
|
||||
return res.status(400).json({ error: 'Invalid email' });
|
||||
}
|
||||
next();
|
||||
};
|
||||
|
||||
app.post('/register', validateEmail, (req, res) => {
|
||||
res.json({ success: true });
|
||||
});
|
||||
\end{verbatim}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile,shrink=20]{Auth middleware}
|
||||
\begin{verbatim}
|
||||
const auth = (req, res, next) => {
|
||||
const token = req.headers.authorization?.split(' ')[1];
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({ error: 'Token required' });
|
||||
}
|
||||
|
||||
try {
|
||||
const decoded = jwt.verify(token, SECRET);
|
||||
req.user = decoded;
|
||||
next();
|
||||
} catch (err) {
|
||||
res.status(403).json({ error: 'Invalid token' });
|
||||
}
|
||||
};
|
||||
|
||||
app.get('/protected', auth, (req, res) => {
|
||||
res.json({ user: req.user });
|
||||
});
|
||||
\end{verbatim}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile,shrink=20]{Role-based middleware}
|
||||
\begin{verbatim}
|
||||
const requireRole = (role) => {
|
||||
return (req, res, next) => {
|
||||
if (req.user.role !== role) {
|
||||
return res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
app.delete('/user/:id', auth, requireRole('admin'), (req, res) => {
|
||||
res.json({ deleted: true });
|
||||
});
|
||||
\end{verbatim}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile,shrink=20]{Error handling middleware}
|
||||
\begin{verbatim}
|
||||
// Mindig utolsóként!
|
||||
app.use((err, req, res, next) => {
|
||||
console.error(err.stack);
|
||||
|
||||
res.status(err.status || 500).json({
|
||||
error: err.message || 'Internal Server Error'
|
||||
});
|
||||
});
|
||||
|
||||
// Használat
|
||||
app.get('/error', (req, res, next) => {
|
||||
const err = new Error('Something broke!');
|
||||
err.status = 500;
|
||||
next(err);
|
||||
});
|
||||
\end{verbatim}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile,shrink=20]{CORS middleware}
|
||||
\begin{verbatim}
|
||||
const cors = require('cors');
|
||||
|
||||
// Minden origin engedélyezése
|
||||
app.use(cors());
|
||||
|
||||
// Specifikus beállítás
|
||||
app.use(cors({
|
||||
origin: 'https://frontend.com',
|
||||
credentials: true,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE']
|
||||
}));
|
||||
\end{verbatim}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[shrink=15]{Built-in middleware}
|
||||
\begin{itemize}
|
||||
\item \texttt{express.json()}: JSON body parsing
|
||||
\item \texttt{express.urlencoded()}: URL-encoded body parsing
|
||||
\item \texttt{express.static()}: Static fájlok kiszolgálása
|
||||
\end{itemize}
|
||||
\begin{exampleblock}{Használat}
|
||||
\texttt{app.use(express.json());}\\
|
||||
\texttt{app.use(express.static('public'));}
|
||||
\end{exampleblock}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[shrink=15]{Third-party middleware}
|
||||
\begin{description}
|
||||
\item[helmet] HTTP security headers
|
||||
\item[morgan] HTTP request logger
|
||||
\item[compression] Response compression (gzip)
|
||||
\item[cookie-parser] Cookie parsing
|
||||
\item[express-session] Session kezelés
|
||||
\item[passport] Authentication
|
||||
\end{description}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[shrink=15]{Middleware best practices}
|
||||
\begin{enumerate}
|
||||
\item Mindig hívd meg \texttt{next()}-et (vagy küldjél választ)
|
||||
\item Error middleware utolsóként
|
||||
\item Sorrendiség számít!
|
||||
\item Global middleware-ek előre (\texttt{cors}, \texttt{helmet})
|
||||
\item Route-specifikus middleware-ek közvetlenül route-hoz
|
||||
\item Async middleware-eknél használj try-catch-et
|
||||
\end{enumerate}
|
||||
\end{frame}
|
||||
Reference in New Issue
Block a user