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, Secure a SameSite.

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
StavStavový (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álovatelnostNutné sdílené úložištěNativní
Přenášená velikostMalá (jeden identifikátor)Větší (podepsané claims)
Napříč doménami / SSOOmezujícíVhodné
Plocha pro XSSNízká u HttpOnly cookieVysoká 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 HttpOnly je nedostupná pro JavaScript, tedy chráněná před krádeží injekcí. JWT uložený v localStorage je naopak čitelný jakýmkoli skriptem, což z něj činí lákavý cíl. Uložení JWT do HttpOnly cookie 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čce Authorization se 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.