JWT vs. session cookies: co skutečně chrání vaše API
JWT není univerzálně lepší než session. Hodí se pro distribuované služby, mobilní klienty a bezstavové API. Session cookie je jednodušší na revokaci a bezpečnější, pokud ji správně nastavíte. Rozhodněte se podle toho, zda potřebujete okamžitě rušit přístup, kolik služeb token ověřuje a jak dlouho může být kompromitován. Ať zvolíte cokoli, testujte chybové stavy: expirovaný token, podvržený podpis, chybějící hlavičku i token z jiného prostředí.
Při ověřování tokenu na serveru kontrolujte podpis, expiraci (exp), případně issuer a audience. Nezapomeňte na rotaci klíčů. Pokud podepisovací klíč unikne, musíte být schopni ho vyměnit, aniž by přestaly fungovat všechny tokeny. Používejte kid (key ID) v hlavičce a mějte připravený seznam platných klíčů. U symetrického klíče volte dostatečnou délku – alespoň 256 bitů – a nikdy ho nedávejte do kódu ani do repozitáře. Načítejte ho z proměnné prostředí nebo z bezpečného úložiště.
Podpis, expirace a bezpečné ukládání První zásadní chybou je ignorování algoritmu. Útočník může změnit hlavičku na „none" nebo podstrčit jiný algoritmus. Vždy explicitně povolte pouze jeden očekávaný algoritmus a odmítněte vše ostatní. Druhou chybou je příliš dlouhá platnost tokenu. Access token by měl žít v řádu minut, maximálně hodin. Delší platnost řešte refresh tokenem, který lze revokovat. Refresh token ukládejte bezpečně – v prohlížeči do httpOnly cookie s atributy Secure a SameSite, nikdy do localStorage. localStorage je přístupný z JavaScriptu, takže při XSS útoku útočník token okamžitě získá.
Nakonec se neboj mazat. Komentovaný kód, který už nikdo nepoužívá, jen mate. Pokud si nejsi jistý, zda něco ještě někde žije, ověř to vyhledáním a teprve pak smaž. Čistý kód není o tom napsat co nejvíc řádků, ale o tom, aby každý z nich měl jasný důvod. Jakmile začneš pochybovat, co která část dělá, je čas ji přejmenovat, rozdělit nebo zahodit.
Základní dělení je na permisivní a copyleftové licence. Permisivní licence, jako MIT, BSD nebo Apache, dovolují kód použít i v uzavřených produktech, stačí zachovat autorskou informaci a text licence. Copyleftové licence, například GPL nebo AGPL, naopak vyžadují, aby odvozená díla zůstala pod stejnou licencí. AGPL navíc řeší situaci, kdy software běží na serveru a uživatel k němu přistupuje po síti – i tehdy vzniká povinnost zpřístupnit zdrojový kód.
JWT se skládá ze tří částí: hlavičky, datové části a podpisu. Hlavička určuje algoritmus, datová část nese takzvané claims – např. identitu uživatele, roli, čas expirace. Podpis zajišťuje integritu. Pokud použijete symetrický algoritmus (HS256), podepisujete i ověřujete stejným klíčem. Asymetrický (RS256) odděluje soukromý klíč pro podpis a veřejný pro ověření, což se hodí, když API ověřuje více služeb. Nikdy neposílejte citlivá data v datové části – JWT je pouze podepsaný, ne zašifrovaný. Kdokoli s tokenem vidí jeho obsah.
Třetím krokem je zvážit, jak chcete řešit pozdější změnu podmínek. Některé projekty používají dvojí licencování nebo přechod na novější verzi licence. Pozor na formulace typu „a pozdější verze" – dávají budoucím příjemcům možnost řídit se i verzí, kterou jste při zveřejnění neznali. Pokud chcete mít jistotu, uveďte konkrétní číslo verze licence.
Scrum v českém týmu funguje, když ho nepřebíráte jako dogmu, ale jako rámec, který si ohnete podle sebe. Nechte si jej alespoň tři měsíce beze změny, teprve pak upravujte. Měřte jednu věc, třeba počet nedokončených položek na konci sprintu, a podle ní se rozhodujte. Pokud se čísla nezlepší, nehledejte chybu v lidech, ale v tom, jak jste nastavili pravidla.
Při návrhu zabezpečení API se často rozhodujete mezi dvěma přístupy: klasickými session cookies a JWT tokeny. Rozdíl není jen v technologii, ale především v tom, kde žije stav přihlášení. Session cookie drží stav na serveru, klient dostane pouze identifikátor. JWT je samonosný token – veškerá data i podpis jsou na straně klienta. To přináší jiné nároky na bezpečnost a jiné chyby.
Čistý kód v JavaScriptu není o estetice, ale o tom, jak rychle dokážete najít chybu a jak snadno někdo jiný pochopí, co jste mysleli. Začněte tím, že budete pojmenovávat věci podle toho, co dělají, ne jak vypadají. Funkce spočtiDaň je lepší než vypocet2. Proměnná aktivníUživatelé je lepší než data. Pokud název potřebuje komentář, je název špatný. Platí to i pro booleany: jePřihlášen, máOprávnění, platíKarta. Vyhněte se zkratkám, které za tři měsíce nepochopíte.
Délka funkcí je druhý nejčastější problém. Funkce, která má přes třicet řádků, obvykle dělá víc věcí. Rozdělte ji podle toho, co se v ní děje: načtení dat, transformace, uložení. Každá část by měla jít otestovat samostatně. Vyhněte se vnořeným podmínkám do hloubky. Místo if (a) if (b) if (c) { … } použijte tzv. guard clauses: na začátku funkce ošetřete neplatné stavy a vraťte se. Tím se sníží počet úrovní a kód se čte shora dolů.