\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}