280 lines
7.6 KiB
TeX
280 lines
7.6 KiB
TeX
\section{Session}
|
|
|
|
\begin{frame}{Mi az a session?}
|
|
\begin{block}{Definíció}
|
|
Szerver-oldali állapot, amely felhasználói adatokat tárol bejelentkezés után.
|
|
\end{block}
|
|
|
|
\begin{itemize}
|
|
\item \textbf{Stateful} megközelítés
|
|
\item Kliens csak \textbf{session ID}-t tárol (cookie)
|
|
\item Tartalom a szerveren (memória/DB/Redis)
|
|
\end{itemize}
|
|
|
|
\begin{alertblock}{Fontos}
|
|
Session auth nem token-alapú, szerver kezeli az állapotot.
|
|
\end{alertblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Session vs Token}
|
|
\begin{columns}
|
|
\begin{column}{0.48\textwidth}
|
|
\begin{block}{Session}
|
|
\begin{itemize}
|
|
\item Szerver tárolja
|
|
\item Cookie-ban ID
|
|
\item Könnyű visszavonás
|
|
\item Nehezebb skálázás
|
|
\end{itemize}
|
|
\end{block}
|
|
\end{column}
|
|
|
|
\begin{column}{0.48\textwidth}
|
|
\begin{block}{Token (JWT)}
|
|
\begin{itemize}
|
|
\item Stateless
|
|
\item Kliens tárolja
|
|
\item Nehezebb visszavonás
|
|
\item Könnyebb skálázás
|
|
\end{itemize}
|
|
\end{block}
|
|
\end{column}
|
|
\end{columns}
|
|
|
|
\begin{center}
|
|
Session $\leftrightarrow$ JWT: kontroll vs skálázhatóság
|
|
\end{center}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Session folyamat}
|
|
\begin{enumerate}
|
|
\item Bejelentkezés (username + password)
|
|
\item Adatok ellenőrzése
|
|
\item \textbf{Session} létrehozás
|
|
\item Session ID cookie-ban
|
|
\item Kliens csatolja minden kéréshez
|
|
\item Szerver ID alapján azonosít
|
|
\end{enumerate}
|
|
|
|
\begin{alertblock}{Megjegyzés}
|
|
HTTPS kötelező, különben session ID elliopható!
|
|
\end{alertblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Session tárolás}
|
|
\begin{block}{Hol tároljuk?}
|
|
Session adatokat szerveren, több lehetőség:
|
|
\end{block}
|
|
|
|
\begin{itemize}
|
|
\item \textbf{In-memory} - gyors, nem skálázható
|
|
\item \textbf{Redis} - gyors, skálázható, TTL
|
|
\item \textbf{DB} - tartós, lassabb
|
|
\item \textbf{Distributed cache} - nagy rendszerekhez
|
|
\end{itemize}
|
|
|
|
\begin{alertblock}{Best Practice}
|
|
Élesben ne használj in-memory store-t!
|
|
\end{alertblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile,shrink=15]{Redis Session Store - Telepítés}
|
|
\begin{block}{Redis előnyei session tároláshoz}
|
|
Gyors, skálázható, beépített TTL (Time To Live) támogatás
|
|
\end{block}
|
|
|
|
\begin{verbatim}
|
|
npm install express-session connect-redis redis
|
|
|
|
// Redis kliens és session store
|
|
const session = require('express-session');
|
|
const RedisStore = require('connect-redis').default;
|
|
const { createClient } = require('redis');
|
|
|
|
const redisClient = createClient({
|
|
host: 'localhost',
|
|
port: 6379
|
|
});
|
|
redisClient.connect();
|
|
\end{verbatim}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile,shrink=15]{Redis Session - Konfiguráció}
|
|
\begin{verbatim}
|
|
app.use(session({
|
|
store: new RedisStore({ client: redisClient }),
|
|
secret: process.env.SESSION_SECRET,
|
|
resave: false,
|
|
saveUninitialized: false,
|
|
cookie: {
|
|
httpOnly: true,
|
|
secure: true, // HTTPS
|
|
maxAge: 1000 * 60 * 60 * 24 // 1 nap
|
|
}
|
|
}));
|
|
|
|
app.post('/login', async (req, res) => {
|
|
const user = await authenticateUser(req.body);
|
|
req.session.userId = user.id;
|
|
req.session.role = user.role;
|
|
res.json({ success: true });
|
|
});
|
|
\end{verbatim}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile,shrink=15]{Redis Session - Műveletek}
|
|
\begin{verbatim}
|
|
// Session olvasása
|
|
app.get('/profile', (req, res) => {
|
|
if (!req.session.userId) {
|
|
return res.status(401).json({ error: 'Not logged in' });
|
|
}
|
|
res.json({ userId: req.session.userId });
|
|
});
|
|
|
|
// Session módosítása
|
|
app.post('/settings', (req, res) => {
|
|
req.session.theme = req.body.theme;
|
|
res.json({ success: true });
|
|
});
|
|
|
|
// Session törlése (logout)
|
|
app.post('/logout', (req, res) => {
|
|
req.session.destroy((err) => {
|
|
if (err) return res.status(500).send('Error');
|
|
res.clearCookie('connect.sid');
|
|
res.json({ message: 'Logged out' });
|
|
});
|
|
});
|
|
\end{verbatim}
|
|
\end{frame}
|
|
|
|
\begin{frame}[shrink=15]{Redis Session előnyei}
|
|
\begin{columns}
|
|
\begin{column}{0.48\textwidth}
|
|
\textbf{Előnyök:}
|
|
\begin{itemize}
|
|
\item Villámgyors (in-memory)
|
|
\item Automatikus TTL támogatás
|
|
\item Skálázható (cluster mode)
|
|
\item Persistence opcionális
|
|
\item Pub/Sub támogatás
|
|
\end{itemize}
|
|
\end{column}
|
|
\begin{column}{0.48\textwidth}
|
|
\textbf{Használati esetek:}
|
|
\begin{itemize}
|
|
\item Session store
|
|
\item Rate limiting
|
|
\item Real-time analytics
|
|
\item Cache layer
|
|
\item Message queue
|
|
\end{itemize}
|
|
\end{column}
|
|
\end{columns}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Session élettartam}
|
|
\begin{block}{Session Timeout}
|
|
Session-ök lejárnak idő vagy inaktivitás után.
|
|
\end{block}
|
|
|
|
\begin{itemize}
|
|
\item \textbf{Absolute:} fix lejárat (pl. 24h)
|
|
\item \textbf{Idle:} aktivitás hiánya
|
|
\item \textbf{Sliding:} aktivitás meghosszabbítja
|
|
\end{itemize}
|
|
|
|
\begin{exampleblock}{Példa}
|
|
Online bank: 5 perc inaktivitás $\to$ kiléptetés.
|
|
\end{exampleblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile,shrink=10]{Express session példa}
|
|
\begin{exampleblock}{express-session használata}
|
|
\tiny
|
|
\begin{verbatim}
|
|
const session = require('express-session');
|
|
|
|
app.use(session({
|
|
secret: 'super-secret-key',
|
|
resave: false,
|
|
saveUninitialized: false,
|
|
cookie: {
|
|
httpOnly: true,
|
|
secure: true,
|
|
maxAge: 1000 * 60 * 60 // 1 óra
|
|
}
|
|
}));
|
|
|
|
app.post('/login', (req, res) => {
|
|
req.session.userId = user.id;
|
|
res.json({ message: 'Logged in' });
|
|
});
|
|
\end{verbatim}
|
|
\end{exampleblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Cookie biztonság}
|
|
\begin{block}{Mitől biztonságos?}
|
|
Session ID cookie biztonságos beállításokkal.
|
|
\end{block}
|
|
|
|
\begin{itemize}
|
|
\item \textbf{HttpOnly}: JS nem fér hozzá
|
|
\item \textbf{Secure}: csak HTTPS
|
|
\item \textbf{SameSite}: CSRF védelem
|
|
\item \textbf{Rotálás}: ID frissítés (fixation ellen)
|
|
\end{itemize}
|
|
|
|
\begin{alertblock}{Session Fixation}
|
|
Támadó előre beállított ID-t "ráerőltet" a felhasználóra.
|
|
\end{alertblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}[shrink=5]{Session alapú autorizáció}
|
|
\begin{block}{Jogosultságok session-ben}
|
|
A session tárolhatja a felhasználó szerepköreit és jogosultságait.
|
|
\end{block}
|
|
|
|
\begin{itemize}
|
|
\item \textbf{Példa:} \texttt{req.session.role = 'Admin'}
|
|
\item Middleware ellenőrzi a role-t
|
|
\item Ha nincs jogosultság: \texttt{403 Forbidden}
|
|
\end{itemize}
|
|
|
|
\vspace{0.4cm}
|
|
|
|
\begin{exampleblock}{Minta ellenőrzés}
|
|
\texttt{if (req.session.role !== 'Admin') return res.status(403);}
|
|
\end{exampleblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}{Session Best Practices}
|
|
\begin{itemize}
|
|
\item HTTPS használata mindenhol
|
|
\item HttpOnly + Secure + SameSite cookie beállítások
|
|
\item Session store: Redis vagy DB
|
|
\item Rövid idle timeout érzékeny rendszereknél
|
|
\item Session ID rotálás bejelentkezéskor
|
|
\item Rate limiting és brute force védelem
|
|
\end{itemize}
|
|
|
|
\vspace{0.5cm}
|
|
|
|
\end{frame}
|
|
|
|
\begin{frame}{Összefoglalás - Session}
|
|
\begin{itemize}
|
|
\item Session = szerver-oldali állapot (cookie csak ID)
|
|
\item Kényelmes, de skálázásnál kihívás
|
|
\item Cookie biztonsági beállítások kritikusak
|
|
\item \textbf{Redis a leggyakoribb session store} - gyors, skálázható
|
|
\item Timeout és rotáció védelem session támadások ellen
|
|
\item Redis TTL automatikus session lejárathoz
|
|
\end{itemize}
|
|
|
|
\begin{exampleblock}{Produkciós környezet}
|
|
Redis cluster + persistence + backup = megbízható session kezelés
|
|
\end{exampleblock}
|
|
\end{frame} |