JWT vs. session: jaký mechanismus ověřování zvolit?
Ověřit uživatele znamená při každém požadavku vědět, kdo to je. Střetávají se dvě velké rodiny: serverové session, kde si server uchovává stopu o přihlášeném uživateli, a JSON Web Tokens (JWT), kde identita putuje v podepsaném tokenu neseném klientem. Volba ovlivňuje bezpečnost, schopnost škálovat a snadnost odhlášení uživatele. Zde je návod, jak se rozhodnout podle vašeho kontextu.
Serverové session (stavové)
U session server při přihlášení vytvoří identifikátor session, uloží související data (identitu, role, košík) na straně serveru (paměť, Redis, databáze) a vrátí prohlížeči cookie obsahující pouze tento identifikátor. Při každém požadavku server přečte cookie, najde session a ví, kdo mluví.
- Stav na straně serveru: zdroj pravdy zůstává na serveru, klient nese jen neprůhlednou referenci.
- Okamžité odvolání: smazání session na straně serveru okamžitě odhlásí uživatele.
- Cookie: přenášená automaticky prohlížečem, ideálně s
HttpOnly,SecureaSameSite.
JSON Web Tokens (bezstavové)
JWT je samonosný token složený ze tří částí kódovaných v base64url a oddělených tečkami: header, payload (claims, například identifikátor uživatele a vypršení) a signature. Server token při přihlášení podepíše; poté mu stačí ověřit podpis, aby obsahu důvěřoval, aniž by cokoli ukládal.
- Bezstavový: veškerá potřebná informace je v tokenu, server nepotřebuje sdílenou paměť.
- Ověřitelný všude: jakákoli služba, která zná klíč, může token validovat, což je praktické pro distribuované architektury a SSO.
- Nástroje: token můžete prozkoumat naším dekodérem JWT, zkontrolovat jeho podpis pomocí verifikátoru JWT nebo si jej vytvořit generátorem JWT.
Srovnávací tabulka
| Kritérium | Serverová session | JWT |
|---|---|---|
| Stav | Stavový (uložen na serveru) | Bezstavový (nesen klientem) |
| Serverové úložiště | Vyžadováno (Redis, databáze) | Žádné |
| Odvolání | Okamžité | Obtížné před vypršením |
| Horizontální škálovatelnost | Nutné sdílené úložiště | Nativní |
| Přenášená velikost | Malá (jeden identifikátor) | Větší (podepsané claims) |
| Napříč doménami / SSO | Omezující | Vhodné |
| Plocha pro XSS | Nízká u HttpOnly cookie | Vysoká při uložení v localStorage |
Bezpečnost: XSS, CSRF a odvolání
Oba přístupy jsou při správné implementaci bezpečné, ale jejich rizika se liší.
- XSS: cookie session s
HttpOnlyje nedostupná pro JavaScript, tedy chráněná před krádeží injekcí. JWT uložený vlocalStorageje naopak čitelný jakýmkoli skriptem, což z něj činí lákavý cíl. Uložení JWT doHttpOnlycookie tuto výhodu JWT ruší, ale znovu zavádí riziko CSRF. - CSRF: cookies se odesílají automaticky, jsou tedy zranitelné vůči CSRF bez ochrany (atribut
SameSite, anti-CSRF token). JWT odeslaný ručně v hlavičceAuthorizationse toho netýká. - Odvolání: to je slabé místo JWT. Protože je samonosný, nelze jej zneplatnit před vypršením, aniž by se znovu zavedl serverový stav (seznam odvolání, blacklist). Session se maže okamžitě.
Škálovatelnost a architektura
Na jediném serveru jsou session triviální. Jakmile rozdělíte zátěž na více instancí, každá instance musí mít přístup k session: je potřeba sdílené úložiště (Redis) nebo sticky sessions. Zde JWT vyniká, protože jakákoli instance validuje token bez síťového volání či společného úložiště.
- Mikroslužby: JWT šíří identitu z jedné služby na druhou bez centrální databáze.
- Veřejná a mobilní API: JWT se vyhýbá správě cookies na straně nativního klienta.
- Klasický monolit: session zůstává jednodušší a ve výchozím nastavení bezpečnější.
Kdy zvolit jedno či druhé
Zvolte session, když
- Vyvíjíte klasickou webovou aplikaci s renderováním na serveru
- Okamžité odvolání je kritické (banky, zdravotnictví, back-office)
- Chcete ve výchozím nastavení nejbezpečnější řešení s nejméně nástrahami
- Vaše infrastruktura zvládne sdílené úložiště session bez potíží
Zvolte JWT, když
- Vystavujete API konzumované SPA, mobilem nebo třetími stranami
- Máte architekturu mikroslužeb nebo SSO mezi doménami
- Musíte škálovat horizontálně bez sdíleného úložiště
- Přijímáte správu krátkého vypršení a obnovování tokenů
Doporučení
Pro většinu webových aplikací zůstávají serverové session nejbezpečnější a nejjednodušší volbou: okamžité odvolání, HttpOnly cookie a nulová správa tokenů na straně klienta. JWT si vyhraďte pro případy, kde jeho bezstavovost přináší skutečnou hodnotu: bezstavová API, mobil, mikroslužby, SSO.
Pokud se rozhodnete pro JWT, udržujte krátkou životnost (několik minut) spárovanou s refresh tokenem uloženým v HttpOnly cookie a počítejte se seznamem odvolání pro citlivé případy. Spojíte tak to nejlepší z obou světů.
Časté dotazy
Je JWT šifrovaný?
Ne, ve výchozím nastavení je JWT pouze podepsaný, nikoli šifrovaný. Jeho payload je kódován v base64url a čitelný pro kohokoli, kdo jej zachytí. Nikdy nevkládejte citlivá data v otevřené podobě do JWT. K šifrování obsahu je třeba sáhnout po JWE (JSON Web Encryption).
Kde uložit JWT na straně klienta?
Nejbezpečnější je HttpOnly, Secure a SameSite cookie, která chrání před krádeží přes XSS. localStorage je jednodušší, ale vystavuje token jakémukoli škodlivému skriptu. Vyhněte se mu u tokenů s vysokými oprávněními.
Jak odhlásit uživatele s JWT?
Protože je token samonosný, skutečné odhlášení vyžaduje buď počkat na jeho vypršení, nebo udržovat seznam odvolání na straně serveru. Proto se používají krátké životnosti a refresh token, který lze naopak odvolat.
Lze kombinovat session a JWT?
Ano, je to běžná praxe: access token JWT s krátkou životností pro volání API a refresh token spravovaný jako session (uložený a odvolatelný na straně serveru) pro obnovování access tokenu.