JWT vs seja: kateri mehanizem preverjanja pristnosti izbrati?

Preveriti pristnost uporabnika pomeni ob vsaki zahtevi vedeti, kdo je. Spopadeta se dve veliki družini: strežniške seje, kjer strežnik beleži prijavljenega uporabnika, in JSON Web Tokens (JWT), kjer identiteta potuje v podpisanem žetonu, ki ga nosi odjemalec. Izbira vpliva na varnost, zmožnost razširjanja in enostavnost odjave uporabnika. Tukaj je, kako se odločiti glede na vaš kontekst.

Strežniške seje (stateful)

Pri seji strežnik ob prijavi ustvari identifikator seje, shrani povezane podatke (identiteta, vloge, košarica) na strani strežnika (pomnilnik, Redis, podatkovna baza) in brskalniku vrne piškotek, ki vsebuje samo ta identifikator. Ob vsaki zahtevi strežnik prebere piškotek, najde sejo in ve, kdo govori.

  • Stanje na strani strežnika: vir resnice ostaja na strežniku, odjemalec nosi le neprozorno referenco.
  • Takojšen preklic: izbris seje na strani strežnika uporabnika takoj odjavi.
  • Piškotek: brskalnik ga pošlje samodejno, idealno z atributi HttpOnly, Secure in SameSite.

JSON Web Tokens (stateless)

JWT je samostojni žeton, sestavljen iz treh delov, kodiranih v base64url in ločenih s pikami: header, payload (zahtevki, na primer identifikator uporabnika in potek) ter podpis. Strežnik ob prijavi žeton podpiše; nato mu zadošča, da preveri podpis in zaupa vsebini, ne da bi karkoli shranjeval.

  • Brez stanja: vse potrebne informacije so v žetonu, strežnik ne potrebuje skupnega pomnilnika.
  • Preverljiv povsod: katera koli storitev, ki pozna ključ, lahko žeton potrdi, kar je priročno za porazdeljene arhitekture in SSO.
  • Orodja: žeton lahko pregledate z našim JWT dekoderjem, preverite njegov podpis z JWT verifikatorjem ali ga ustvarite z JWT generatorjem.

Primerjalna tabela

Merilo Strežniška seja JWT
StanjeStateful (shranjeno na strežniku)Stateless (nosi ga odjemalec)
Shramba na strežnikuZahtevana (Redis, baza)Nobena
PreklicTakojšenTežaven pred potekom
Vodoravna razširljivostPotrebna skupna shrambaNaravna
Velikost prenosaMajhna (en identifikator)Večja (podpisani zahtevki)
Med domenami / SSOOmejujočePrimerno
Površina XSSNizka, če je piškotek HttpOnlyVisoka, če je shranjen v localStorage

Varnost: XSS, CSRF in preklic

Oba pristopa sta varna, če sta dobro implementirana, vendar se njuna tveganja razlikujejo.

  • XSS: piškotek seje HttpOnly je nedostopen JavaScriptu, zato zaščiten pred krajo z vrivanjem. JWT, shranjen v localStorage, pa lahko prebere vsaka skripta, kar ga naredi za priljubljeno tarčo. Shranjevanje JWT v piškotek HttpOnly izniči to prednost JWT, a ponovno uvede tveganje CSRF.
  • CSRF: piškotki se pošiljajo samodejno, zato so brez zaščite ranljivi za CSRF (atribut SameSite, žeton proti CSRF). JWT, ročno poslan v glavi Authorization, ni izpostavljen.
  • Preklic: to je šibka točka JWT. Ker je samostojen, ga pred potekom ni mogoče razveljaviti brez ponovne uvedbe strežniškega stanja (seznam preklicev, črni seznam). Seja se izbriše takoj.

Razširljivost in arhitektura

Na enem samem strežniku so seje trivialne. Takoj ko obremenitev porazdelite na več instanc, mora vsaka instanca dostopati do sej: potrebna je skupna shramba (Redis) ali lepljive seje. JWT tukaj zablesti, saj katera koli instanca potrdi žeton brez omrežnega klica ali skupne shrambe.

  • Mikrostoritve: JWT prenese identiteto iz ene storitve v drugo brez osrednje baze.
  • Javni in mobilni API-ji: JWT se izogne upravljanju piškotkov na strani nativnega odjemalca.
  • Klasičen monolit: seja ostaja enostavnejša in privzeto varnejša.

Kdaj izbrati enega ali drugega

Izberite seje, kadar

  • Razvijate klasično spletno aplikacijo z izrisom na strežniku
  • Takojšen preklic je ključen (bančništvo, zdravje, zaledje)
  • Želite privzeto najvarnejšo rešitev z najmanj pastmi
  • Vaša infrastruktura brez težav prenese skupno shrambo sej

Izberite JWT, kadar

  • Izpostavljate API, ki ga uporabljajo SPA, mobilne aplikacije ali tretje osebe
  • Imate arhitekturo mikrostoritev ali SSO med domenami
  • Morate se vodoravno razširjati brez skupne shrambe
  • Sprejmete upravljanje kratkega poteka in osveževanja žetonov

Priporočilo

Za večino spletnih aplikacij strežniške seje ostajajo najvarnejša in najenostavnejša izbira: takojšen preklic, piškotek HttpOnly in nič upravljanja žetonov na strani odjemalca. JWT prihranite za primere, kjer njegova odsotnost stanja prinaša pravo vrednost: stateless API, mobilne aplikacije, mikrostoritve, SSO.

Če se odločite za JWT, ohranite kratko življenjsko dobo (nekaj minut) skupaj z žetonom za osvežitev, shranjenim v piškotku HttpOnly, in predvidite seznam preklicev za občutljive primere. Tako združite najboljše iz obeh svetov.

Pogosta vprašanja

Ali je JWT šifriran?

Ne, privzeto je JWT samo podpisan, ne šifriran. Njegov payload je kodiran v base64url in berljiv vsakomur, ki ga prestreže. Nikoli ne postavljajte občutljivih podatkov v JWT v čistem besedilu. Za šifriranje vsebine je treba uporabiti JWE (JSON Web Encryption).

Kje shraniti JWT na strani odjemalca?

Najvarnejši je piškotek HttpOnly, Secure in SameSite, ki ščiti pred krajo z XSS. localStorage je enostavnejši, a žeton izpostavi vsaki zlonamerni skripti. Izogibajte se mu za žetone z visokimi pravicami.

Kako odjaviti uporabnika z JWT?

Ker je žeton samostojen, prava odjava zahteva bodisi čakanje na potek bodisi vodenje seznama preklicev na strani strežnika. Zato uporabljamo kratke življenjske dobe in žeton za osvežitev, ki ga lahko prekličemo.

Ali je mogoče združiti seje in JWT?

Da, to je pogosta praksa: JWT dostopni žeton s kratko življenjsko dobo za klice API in žeton za osvežitev, voden kot seja (shranjen in preklicljiv na strani strežnika), za obnovo dostopnega žetona.