\section{JWT}

\begin{frame}{Mi az a JWT?}
  \begin{block}{JSON Web Token (RFC 7519)}
    Nyílt szabványú, kompakt és önálló módszer információ biztonságos továbbítására.
  \end{block}
  
  \begin{itemize}
    \item \textbf{Kompakt:} Kis méret, URL/header-ben is
    \item \textbf{Önálló:} Minden információt tartalmaz
    \item \textbf{Biztonságos:} Digitálisan aláírt
    
    \item \textbf{Használat:}
      \begin{itemize}
        \item Authentikáció
        \item Információ csere
        \item Stateless session
      \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile,shrink=10]{JWT formátum}
  \begin{block}{Három részből áll, ponttal elválasztva}
    \texttt{\textcolor{red}{HEADER}.\textcolor{purple}{PAYLOAD}.\textcolor{blue}{SIGNATURE}}
  \end{block}
  
  \begin{exampleblock}{Példa JWT}
    \tiny
    \begin{verbatim}
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZ
SI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36P
OkmLXOUqhfKJ4
    \end{verbatim}
  \end{exampleblock}
  
  \begin{itemize}
    \item \textcolor{red}{\textbf{Header:}} Token típusa és algoritmus
    \item \textcolor{purple}{\textbf{Payload:}} Claims (állítások) - felhasználói adatok
    \item \textcolor{blue}{\textbf{Signature:}} Aláírás - integritás ellenőrzés
  \end{itemize}
  
  \begin{alertblock}{Fontos!}
    A JWT Base64URL kódolású, \textbf{NEM} titkosított! A payload tartalma olvasható!
  \end{alertblock}
\end{frame}

\begin{frame}[fragile]{JWT Header}
  \begin{block}{Token metaadatok}
    Token típusa és aláírási algoritmus.
  \end{block}
  
  \begin{columns}
    \begin{column}{0.48\textwidth}
      \textbf{JSON:}
      \begin{verbatim}
{
  "alg": "HS256",
  "typ": "JWT"
}
      \end{verbatim}
      
      \begin{itemize}
        \item \texttt{alg}: Algoritmus
        \item \texttt{typ}: Token típus
      \end{itemize}
    \end{column}
    
    \begin{column}{0.48\textwidth}
      \textbf{Kódolt:}
      \begin{verbatim}
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
      \end{verbatim}
      
      \textbf{Algoritmusok:}
      \begin{itemize}
        \item HS256 - HMAC
        \item RS256 - RSA
        \item ES256 - ECDSA
      \end{itemize}
    \end{column}
  \end{columns}
\end{frame}

\begin{frame}[fragile,shrink=5]{JWT Payload (Claims)}
  \begin{block}{Felhasználói adatok és meta}
    Claims (allítoltak) a felhasználóról és tokenről.
  \end{block}
  
  \begin{columns}
    \begin{column}{0.48\textwidth}
      \textbf{Registered:}
      \begin{itemize}
        \item \texttt{iss} - Kibocsátó
        \item \texttt{sub} - Tárgy/user ID
        \item \texttt{aud} - Címzett
        \item \texttt{exp} - Lejárat
        \item \texttt{iat} - Kiállítás
      \end{itemize}
    \end{column}
    
    \begin{column}{0.48\textwidth}
      \textbf{Példa:}
      \small
      \begin{verbatim}
{
  "sub": "1234567890",
  "name": "John Doe",
  "role": "admin",
  "iat": 1516239022,
  "exp": 1516242622
}
      \end{verbatim}
    \end{column}
  \end{columns}
  
  \begin{alertblock}{Figyelem!}
    Ne tároljunk érzékeny adatokat (jelszó) payload-ban!
  \end{alertblock}
\end{frame}

\begin{frame}[fragile,shrink=5]{JWT Signature}
  \begin{block}{Digitális aláírás}
    Biztosítja a token integritását és hitelességét.
  \end{block}
  
  \textbf{Signature (HMAC SHA256):}
  \begin{verbatim}
HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)
  \end{verbatim}
  
  \begin{columns}
    \begin{column}{0.48\textwidth}
      \textbf{HMAC (Symmetric):}
      \begin{itemize}
        \item Egy kulcs
        \item Gyorsabb
        \item HS256
      \end{itemize}
    \end{column}
    
    \begin{column}{0.48\textwidth}
      \textbf{RSA (Asymmetric):}
      \begin{itemize}
        \item Privát + publikus
        \item Biztonságosabb
        \item RS256
      \end{itemize}
    \end{column}
  \end{columns}
\end{frame}

\begin{frame}{JWT működése}
  \begin enumerate}
    \item \textbf{Bejelentkezés:}
      \begin{itemize}
        \item Username + password
        \item Szerver validál
      \end{itemize}
    
    \item \textbf{Token generálás:}
      \begin{itemize}
        \item JWT létrehozás user adatokkal
        \item Aláírás titkos kulccsal
      \end{itemize}
    
    \item \textbf{Tárolás:}
      \begin{itemize}
        \item localStorage / cookie
      \end{itemize}
    
    \item \textbf{API kérések:}
      \begin{itemize}
        \item \texttt{Authorization: Bearer <token>}
        \item Szerver validálja
      \end{itemize}
  \end{enumerate}
\end{frame}

\begin{frame}[fragile,shrink=10]{JWT generálás Node.js-ben}
  \begin{block}{jsonwebtoken könyvtár használata}
    \small
    \begin{verbatim}
const jwt = require('jsonwebtoken');

const payload = {
  userId: user.id,
  email: user.email,
  role: user.role
};

const token = jwt.sign(
  payload, 
  process.env.JWT_SECRET,
  { expiresIn: '1h', issuer: 'myapp' }
);

res.json({ token, expiresIn: 3600 });
    \end{verbatim}
  \end{block}
\end{frame}

\begin{frame}[fragile,shrink=10]{JWT validálás Node.js-ben}
  \begin{block}{Token ellenőrzés}
    \small
    \begin{verbatim}
const authHeader = req.headers.authorization;
const token = authHeader?.split(' ')[1];

if (!token) {
  return res.status(401).json({ error: 'No token' });
}

try {
  const decoded = jwt.verify(token, process.env.JWT_SECRET);
  req.user = decoded;
  next();
} catch (error) {
  return res.status(403).json({ error: 'Invalid' });
}
    \end{verbatim}
  \end{block}
\end{frame}

\begin{frame}[fragile,shrink=10]{JWT middleware Express-ben}
  \begin{block}{Védett route-ok}
    \small
    \begin{verbatim}
const authenticateJWT = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  
  if (!token) return res.status(401).json({ error: 'Token required' });
  
  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) return res.status(403).json({ error: 'Invalid token' });
    req.user = user;
    next();
  });
};

app.get('/api/protected', authenticateJWT, (req, res) => {
  res.json({ message: 'Protected', user: req.user });
});
    \end{verbatim}
  \end{block}
\end{frame}

\begin{frame}{JWT vs Session}
  \begin{columns}
    \begin{column}{0.48\textwidth}
      \begin{block}{JWT (Stateless)}
        \textbf{Előnyök:}
        \begin{itemize}
          \item Skálázható
          \item Nincs szerver-oldali tárolás
          \item Cross-domain működés
          \item Mobile-friendly
        \end{itemize}
        
        \vspace{0.3cm}
        
        \textbf{Hátrányok:}
        \begin{itemize}
          \item Nehéz visszavonni
          \item Token méret
          \item XSS sebezhetőség (localStorage)
        \end{itemize}
      \end{block}
    \end{column}
    
    \begin{column}{0.48\textwidth}
      \begin{block}{Session (Stateful)}
        \textbf{Előnyök:}
        \begin{itemize}
          \item Azonnali visszavonás
          \item Kis cookie méret
          \item Biztonságosabb token tárolás
        \end{itemize}
        
        \vspace{0.3cm}
        
        \textbf{Hátrányok:}
        \begin{itemize}
          \item Szerver-oldali memória
          \item Nehezebb skálázás
          \item CORS problémák
          \item Session store szükséges
        \end{itemize}
      \end{block}
    \end{column}
  \end{columns}
  
  \vspace{0.5cm}
  
  \begin{alertblock}{Melyiket válasszuk?}
    Függ az alkalmazás követelményeitől: méret, skálázhatóság, biztonság, komplexitás.
  \end{alertblock}
\end{frame}

\begin{frame}{Token tárolás a kliens oldalon}
  \begin{columns}
    \begin{column}{0.48\textwidth}
      \begin{block}{localStorage}
        \begin{itemize}
          \item Egyszerű
          \item JS hozzáférés
          \item Megosztott
        \end{itemize}
        
        \textcolor{red}{\textbf{XSS!}}
        \begin{itemize}
          \item \textcolor{red}{JS hozzáférhet}
        \end{itemize}
      \end{block}
    \end{column}
    
    \begin{column}{0.48\textwidth}
      \begin{block}{HttpOnly Cookie}
        \begin{itemize}
          \item JS NEM fér hozzá
          \item Automatikus
          \item XSS védett
        \end{itemize}
        
        \textcolor{red}{\textbf{CSRF}}
        \begin{itemize}
          \item \textcolor{red}{Védelem kell}
        \end{itemize}
      \end{block}
    \end{column}
  \end{columns}
  
  \begin{exampleblock}{Ajánlás}
    HttpOnly, Secure, SameSite cookie a legbiztonságosabb.
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{JWT tárolás HttpOnly Cookie-ban}
  \begin{block}{Token beállítás cookie-ban}
    \small
    \begin{verbatim}
// Login endpoint
app.post('/api/login', (req, res) => {
  // ... authentikáció logika ...
  
  const token = jwt.sign(payload, secret, { expiresIn: '1h' });
  
  res.cookie('token', token, {
    httpOnly: true,    // JavaScript nem férhet hozzá
    secure: true,      // Csak HTTPS-en keresztül
    sameSite: 'strict',// CSRF védelem
    maxAge: 3600000    // 1 óra milliszekundumban
  });
  
  res.json({ success: true, message: 'Logged in' });
});
    \end{verbatim}
  \end{block}
\end{frame}

\begin{frame}[fragile]{JWT olvasás Cookie-ból}
  \begin{block}{Cookie-parser middleware}
    \small
    \begin{verbatim}
const cookieParser = require('cookie-parser');
app.use(cookieParser());

const authenticateJWT = (req, res, next) => {
  // Token a cookie-ból
  const token = req.cookies.token;
  
  if (!token) {
    return res.status(401).json({ error: 'Not authenticated' });
  }
  
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    return res.status(403).json({ error: 'Invalid token' });
  }
};
    \end{verbatim}
  \end{block}
\end{frame}

\begin{frame}[shrink=5]{Refresh Token stratégia}
  \begin{block}{Miért szükséges?}
    Access tokenek rövidek (15 perc). Refresh tokennel új access token kérhető.
  \end{block}
  
  \begin{itemize}
    \item \textbf{Access Token:}
      \begin{itemize}
        \item Rövid (15-60 perc)
        \item API kérésekhez
      \end{itemize}
    
    \item \textbf{Refresh Token:}
      \begin{itemize}
        \item Hosszú (7-30 nap)
        \item Új access tokenhez
        \item HttpOnly cookie-ban
        \item DB-ben tárolva
      \end{itemize}
  \end{itemize}
  
  \begin{alertblock}{Best Practice}
    Refresh token rotation: minden refresh-nél új refresh token is.
  \end{alertblock}
\end{frame}

\begin{frame}[fragile]{Refresh Token implementáció}
  \begin{block}{Token refresh endpoint}
    \small
    \begin{verbatim}
app.post('/api/refresh', (req, res) => {
  const refreshToken = req.cookies.refreshToken;
  
  if (!refreshToken) {
    return res.status(401).json({ error: 'No refresh token' });
  }
  
  try {
    // Refresh token validálás
    const decoded = jwt.verify(refreshToken, process.env.REFRESH_SECRET);
    
    // Ellenőrizzük az adatbázisban
    const storedToken = await RefreshToken.findOne({ 
      token: refreshToken, 
      userId: decoded.userId 
    });
    
    if (!storedToken) {
      return res.status(403).json({ error: 'Invalid refresh token' });
    }
    \end{verbatim}
  \end{block}
\end{frame}

\begin{frame}[fragile]{Refresh Token implementáció (folyt.)}
  \begin{block}{Új tokenek generálása}
    \small
    \begin{verbatim}
    // Új access token
    const accessToken = jwt.sign(
      { userId: decoded.userId, role: decoded.role },
      process.env.JWT_SECRET,
      { expiresIn: '15m' }
    );
    
    // Új refresh token (rotation)
    const newRefreshToken = jwt.sign(
      { userId: decoded.userId },
      process.env.REFRESH_SECRET,
      { expiresIn: '7d' }
    );
    
    // Régi token törlése, új mentése az adatbázisba
    await RefreshToken.deleteOne({ token: refreshToken });
    await RefreshToken.create({ token: newRefreshToken, userId: decoded.userId });
    
    res.cookie('refreshToken', newRefreshToken, { httpOnly: true, ... });
    res.json({ accessToken });
  } catch (error) {
    res.status(403).json({ error: 'Invalid refresh token' });
  }
});
    \end{verbatim}
  \end{block}
\end{frame}

\begin{frame}[shrink=5]{JWT biztonság best practices}
  \begin{alertblock}{Kritikus pontok}
    \begin{itemize}
      \item \textbf{Titkos kulcs:} Erős, random, env-ben
      \item \textbf{HTTPS:} Mindig!
      \item \textbf{Lejárat:} Max 1 óra
      \item \textbf{Érzeky adatok:} Ne JWT-ben
      \item \textbf{Algoritmus:} Ellenőrizd (ne 'none')
    \end{itemize}
  \end{alertblock}
  
  \begin{block}{További ajánlások}
    \begin{itemize}
      \item HttpOnly cookie
      \item Refresh token rotation
      \item Rate limiting
      \item Aud és Iss validálás
    \end{itemize}
  \end{block}
\end{frame}

\begin{frame}{Gyakori JWT hibák és támadások}
  \begin{alertblock}{Gyakori sebezhetőségek}
    \begin{enumerate}
      \item \textbf{None algoritmus támadás}
        \begin{itemize}
          \item Header: \texttt{"alg": "none"} - aláírás nélküli token
          \item Védelem: Mindig ellenőrizzük az algoritmust
        \end{itemize}
      
      \item \textbf{Gyenge titkos kulcs}
        \begin{itemize}
          \item Rövid vagy közismert kulcs
          \item Védelem: Min. 256-bit random kulcs
        \end{itemize}
      
      \item \textbf{Token kiszivárogtatás}
        \begin{itemize}
          \item XSS támadás localStorage-ból
          \item Védelem: HttpOnly cookie használata
        \end{itemize}
      
      \item \textbf{Algoritmus konfúzió}
        \begin{itemize}
          \item RS256 publikus kulcs HMAC secret-ként használva
          \item Védelem: Explicit algoritmus megadása validáláskor
        \end{itemize}
    \end{enumerate}
  \end{alertblock}
\end{frame}

\begin{frame}{Összefoglalás}
  \begin{itemize}
    \item \textbf{JWT} = Kompakt, önálló, biztonságos token formátum
    \item \textbf{Struktúra:} Header.Payload.Signature
    \item \textbf{Előnyök:} Stateless, skálázható, cross-domain
    \item \textbf{Claims:} Registered (exp, iat, sub) és Custom (role, email)
    \item \textbf{Tárolás:} HttpOnly cookie a legbiztonságosabb
    \item \textbf{Refresh token:} Új access token kéréshez hosszú élettartammal
    \item \textbf{Biztonság:} HTTPS, erős secret, rövid lejárat, validálás
  \end{itemize}
  
  \vspace{0.5cm}
  
  \begin{exampleblock}{Mikor használjuk a JWT-t?}
    \begin{itemize}
      \item RESTful API authentikáció
      \item Microservice architektúra
      \item Mobile alkalmazások
      \item Single Page Applications (SPA)
      \item Stateless session kezelés
    \end{itemize}
  \end{exampleblock}
\end{frame}
