JWT vs Relácia: ktorý mechanizmus autentifikácie zvoliť?
Autentifikovať používateľa znamená pri každej požiadavke vedieť, kto je. Stretávajú sa dve veľké rodiny: serverové relácie, kde si server uchováva záznam o prihlásenom používateľovi, a JSON Web Tokens (JWT), kde identita cestuje v podpísanom tokene nesenom klientom. Voľba ovplyvňuje bezpečnosť, schopnosť škálovať a jednoduchosť odhlásenia používateľa. Tu je návod, ako sa rozhodnúť podľa vášho kontextu.
Serverové relácie (stateful)
Pri relácii server pri prihlásení vytvorí identifikátor relácie, uloží súvisiace údaje (identita, role, košík) na strane servera (pamäť, Redis, databáza) a vráti prehliadaču cookie obsahujúce len tento identifikátor. Pri každej požiadavke server načíta cookie, nájde reláciu a vie, kto hovorí.
- Stav na strane servera: zdroj pravdy zostáva na serveri, klient nesie len neprehľadnú referenciu.
- Okamžité zrušenie: vymazanie relácie na strane servera okamžite odhlási používateľa.
- Cookie: automaticky prenášané prehliadačom, ideálne v režime
HttpOnly,SecureaSameSite.
JSON Web Tokens (stateless)
JWT je samonosný token zložený z troch častí kódovaných v base64url a oddelených bodkami: header, payload (claimy, napríklad identifikátor používateľa a expirácia) a podpis. Server podpíše token pri prihlásení; potom mu stačí overiť podpis, aby dôveroval obsahu, bez toho aby čokoľvek ukladal.
- Bez stavu: všetky potrebné informácie sú v tokene, server nepotrebuje zdieľanú pamäť.
- Overiteľný kdekoľvek: ktorákoľvek služba, ktorá pozná kľúč, môže token overiť, praktické pre distribuované architektúry a SSO.
- Nástroje: token môžete preskúmať naším dekodérom JWT, skontrolovať jeho podpis overovateľom JWT alebo vytvoriť token generátorom JWT.
Porovnávacia tabuľka
| Kritérium | Serverová relácia | JWT |
|---|---|---|
| Stav | Stateful (uložené na serveri) | Stateless (nesené klientom) |
| Úložisko na serveri | Vyžadované (Redis, databáza) | Žiadne |
| Zrušenie | Okamžité | Ťažké pred expiráciou |
| Horizontálna škálovateľnosť | Potrebné zdieľané úložisko | Natívna |
| Prenášaná veľkosť | Malá (jeden identifikátor) | Väčšia (podpísané claimy) |
| Medzi doménami / SSO | Obmedzujúce | Vhodné |
| Plocha pre XSS | Nízka ak cookie HttpOnly | Vysoká ak uložené v localStorage |
Bezpečnosť: XSS, CSRF a zrušenie
Oba prístupy sú bezpečné, ak sú dobre implementované, ale ich riziká sa líšia.
- XSS: cookie relácie s atribútom
HttpOnlyje pre JavaScript neprístupné, teda chránené pred krádežou prostredníctvom injekcie. JWT uložené vlocalStorageje naopak čitateľné akýmkoľvek skriptom, čo z neho robí ideálny cieľ. Uloženie JWT do cookieHttpOnlyruší túto výhodu JWT, ale opätovne zavádza riziko CSRF. - CSRF: cookies sa odosielajú automaticky, teda zraniteľné voči CSRF bez ochrany (atribút
SameSite, anti-CSRF token). JWT odoslané ručne v hlavičkeAuthorizationsa to netýka. - Zrušenie: to je slabé miesto JWT. Keďže je samonosný, nedá sa zneplatniť pred jeho expiráciou bez opätovného zavedenia serverového stavu (zoznam zrušení, blacklist). Relácia sa vymaže okamžite.
Škálovateľnosť a architektúra
Na jedinom serveri sú relácie triviálne. Akonáhle rozložíte záťaž na viacero inštancií, každá inštancia musí mať prístup k reláciám: je potrebné zdieľané úložisko (Redis) alebo sticky sessions. JWT tu vyniká, pretože ktorákoľvek inštancia overí token bez sieťového volania a bez spoločného úložiska.
- Mikroslužby: JWT prenáša identitu z jednej služby do druhej bez centrálnej databázy.
- Verejné a mobilné API: JWT sa vyhýba správe cookies na strane natívneho klienta.
- Klasický monolit: relácia zostáva jednoduchšia a v predvolenom nastavení bezpečnejšia.
Kedy zvoliť jedno alebo druhé
Zvoľte relácie, keď
- Vyvíjate klasickú webovú aplikáciu so serverovým renderovaním
- Okamžité zrušenie je kritické (banka, zdravotníctvo, back-office)
- Chcete v predvolenom nastavení najbezpečnejšie riešenie s najmenej úskaliami
- Vaša infraštruktúra bez problémov zvládne zdieľané úložisko relácií
Zvoľte JWT, keď
- Vystavujete API spotrebovávané SPA, mobilom alebo tretími stranami
- Máte architektúru mikroslužieb alebo SSO medzi doménami
- Musíte škálovať horizontálne bez zdieľaného úložiska
- Prijímate správu krátkej expirácie a obnovovanie tokenov
Odporúčanie
Pre väčšinu webových aplikácií zostávajú serverové relácie najbezpečnejšou a najjednoduchšou voľbou: okamžité zrušenie, cookie HttpOnly a nulová správa tokenu na strane klienta. JWT si vyhraďte pre prípady, kde jeho bezstavovosť prináša skutočnú hodnotu: stateless API, mobil, mikroslužby, SSO.
Ak sa rozhodnete pre JWT, ponechajte krátku dobu platnosti (niekoľko minút) spojenú s refresh tokenom uloženým v cookie HttpOnly a pre citlivé prípady počítajte so zoznamom zrušení. Skombinujete tak to najlepšie z oboch svetov.
Časté otázky
Je JWT šifrovaný?
Nie, v predvolenom nastavení je JWT len podpísaný, nie šifrovaný. Jeho payload je kódovaný v base64url a čitateľný kýmkoľvek, kto ho zachytí. Nikdy nevkladajte citlivé údaje v čitateľnej podobe do JWT. Na šifrovanie obsahu treba siahnuť po JWE (JSON Web Encryption).
Kde uložiť JWT na strane klienta?
Najbezpečnejšie je cookie HttpOnly, Secure a SameSite, ktoré chráni pred krádežou prostredníctvom XSS. localStorage je jednoduchšie, ale vystavuje token každému škodlivému skriptu. Vyhnite sa mu pri tokenoch s vysokými oprávneniami.
Ako odhlásiť používateľa pomocou JWT?
Keďže token je samonosný, skutočné odhlásenie vyžaduje buď počkať na jeho expiráciu, alebo viesť zoznam zrušení na strane servera. Preto sa používajú krátke doby platnosti a refresh token, ktorý sa dá zrušiť.
Dajú sa skombinovať relácie a JWT?
Áno, je to bežná prax: access token JWT s krátkou dobou platnosti pre volania API a refresh token spravovaný ako relácia (uložený a zrušiteľný na strane servera) na obnovenie access tokenu.