JWT pret sesiju: kuru autentifikācijas mehānismu izvēlēties?

Autentificēt lietotāju nozīmē katra pieprasījuma laikā zināt, kas viņš ir. Saduras divas lielas saimes: servera sesijas, kur serveris seko pieslēgtajam lietotājam, un JSON Web Token (JWT), kur identitāte ceļo klienta nestā parakstītā marķierī. Izvēle ietekmē drošību, mērogošanas spēju un lietotāja atvienošanas vieglumu. Lūk, kā izlemt atkarībā no jūsu konteksta.

Servera sesijas (stateful)

Izmantojot sesiju, serveris pieslēgšanās brīdī izveido sesijas identifikatoru, saglabā saistītos datus (identitāti, lomas, grozu) servera pusē (atmiņā, Redis, datubāzē) un atgriež pārlūkam sīkdatni, kas satur tikai šo identifikatoru. Katra pieprasījuma laikā serveris nolasa sīkdatni, atrod sesiju un zina, kas runā.

  • Stāvoklis servera pusē: patiesības avots paliek serverī, klients nes tikai necaurspīdīgu atsauci.
  • Tūlītēja atsaukšana: sesijas dzēšana servera pusē acumirklī atvieno lietotāju.
  • Sīkdatne: pārlūks pārsūta automātiski, ideālā gadījumā ar HttpOnly, Secure un SameSite.

JSON Web Token (stateless)

JWT ir pašnesošs marķieris, kas sastāv no trim base64url kodētām daļām, atdalītām ar punktiem: galvenes, lietderīgās slodzes (claim'iem, piemēram, lietotāja identifikatora un derīguma termiņa) un paraksta. Serveris paraksta marķieri pieslēgšanās brīdī; pēc tam tam pietiek pārbaudīt parakstu, lai uzticētos saturam, neko nesaglabājot.

  • Bez stāvokļa: visa nepieciešamā informācija ir marķierī, serverim nav vajadzīga koplietota atmiņa.
  • Pārbaudāms visur: jebkurš pakalpojums, kas zina atslēgu, var validēt marķieri, ērti sadalītām arhitektūrām un SSO.
  • Rīki: marķieri varat pārbaudīt ar mūsu JWT dekodētāju, kontrolēt tā parakstu ar JWT verificētāju vai izveidot jaunu ar JWT ģeneratoru.

Salīdzinājuma tabula

Kritērijs Servera sesija JWT
StāvoklisStateful (saglabāts serverī)Stateless (nes klients)
Glabāšana serverīNepieciešama (Redis, datubāze)Nav
AtsaukšanaTūlītējaSarežģīta pirms derīguma termiņa
Horizontāla mērogojamībaNepieciešama koplietota krātuveDabiska
Pārsūtītais izmērsMazs (viens identifikators)Lielāks (parakstīti claim'i)
Starpdomēnu / SSOIerobežojošsPiemērots
XSS virsmaZema, ja sīkdatne HttpOnlyAugsta, ja glabāts localStorage

Drošība: XSS, CSRF un atsaukšana

Abas pieejas ir drošas, ja tās ir pareizi ieviestas, taču to riski atšķiras.

  • XSS: HttpOnly sesijas sīkdatne nav pieejama JavaScript, tāpēc aizsargāta no zādzības caur injekciju. JWT, kas glabāts localStorage, savukārt ir nolasāms jebkuram skriptam, kas padara to par iecienītu mērķi. JWT glabāšana HttpOnly sīkdatnē anulē šo JWT priekšrocību, bet atkal ievieš CSRF risku.
  • CSRF: sīkdatnes tiek nosūtītas automātiski, tāpēc bez aizsardzības ievainojamas pret CSRF (SameSite atribūts, anti-CSRF marķieris). JWT, kas manuāli nosūtīts Authorization galvenē, nav ietekmēts.
  • Atsaukšana: tā ir JWT vājā vieta. Tā kā tas ir pašnesošs, to nevar padarīt nederīgu pirms derīguma termiņa, neieviešot servera stāvokli (atsaukšanas sarakstu, melno sarakstu). Sesija tiek dzēsta acumirklī.

Mērogojamība un arhitektūra

Vienā serverī sesijas ir vienkāršas. Tiklīdz sadalāt slodzi pa vairākiem gadījumiem, katram gadījumam jāpiekļūst sesijām: vajadzīga koplietota krātuve (Redis) vai sticky sesijas. JWT šeit izceļas, jo jebkurš gadījums validē marķieri bez tīkla izsaukuma vai kopīgas glabāšanas.

  • Mikropakalpojumi: JWT pārsūta identitāti no viena pakalpojuma uz citu bez centrālās datubāzes.
  • Publiskas API un mobilās ierīces: JWT izvairās no sīkdatņu pārvaldības natīvā klienta pusē.
  • Klasisks monolīts: sesija paliek vienkāršāka un drošāka pēc noklusējuma.

Kad izvēlēties vienu vai otru

Izvēlēties sesijas, kad

  • Izstrādājat klasisku tīmekļa lietotni ar servera puses renderēšanu
  • Tūlītēja atsaukšana ir kritiski svarīga (banka, veselība, back-office)
  • Vēlaties drošāko risinājumu pēc noklusējuma, ar vismazāk slazdiem
  • Jūsu infrastruktūra bez grūtībām notur koplietotu sesiju krātuvi

Izvēlēties JWT, kad

  • Piedāvājat API, ko izmanto SPA, mobilās ierīces vai trešās puses
  • Jums ir mikropakalpojumu arhitektūra vai SSO starp domēniem
  • Jums jāmērogojas horizontāli bez koplietotas krātuves
  • Piekrītat pārvaldīt īso derīguma termiņu un marķieru atjaunošanu

Ieteikums

Vairumam tīmekļa lietotņu servera sesijas paliek drošākā un vienkāršākā izvēle: tūlītēja atsaukšana, HttpOnly sīkdatne un nekādas marķieru pārvaldības klienta pusē. Rezervējiet JWT gadījumiem, kad tā bezstāvokļa daba sniedz patiesu vērtību: stateless API, mobilās ierīces, mikropakalpojumi, SSO.

Ja izvēlaties JWT, saglabājiet īsu derīguma termiņu (dažas minūtes) apvienojumā ar atsvaidzināšanas marķieri (refresh token), kas glabāts HttpOnly sīkdatnē, un paredziet atsaukšanas sarakstu jutīgiem gadījumiem. Tā jūs apvienojat labāko no abām pasaulēm.

Biežāk uzdotie jautājumi

Vai JWT ir šifrēts?

Nē, pēc noklusējuma JWT ir tikai parakstīts, nevis šifrēts. Tā lietderīgā slodze ir kodēta base64url un nolasāma ikvienam, kas to pārtver. Nekad nelieciet jutīgus datus atklātā tekstā JWT. Lai šifrētu saturu, jāizmanto JWE (JSON Web Encryption).

Kur glabāt JWT klienta pusē?

Visdrošākā ir HttpOnly, Secure un SameSite sīkdatne, kas aizsargā no zādzības caur XSS. localStorage ir vienkāršāks, bet pakļauj marķieri jebkuram ļaunprātīgam skriptam. Izvairieties no tā augsta privilēģiju līmeņa marķieriem.

Kā atvienot lietotāju ar JWT?

Tā kā marķieris ir pašnesošs, reāla atvienošana prasa vai nu gaidīt tā derīguma termiņa beigas, vai uzturēt atsaukšanas sarakstu servera pusē. Tāpēc izmanto īsus derīguma termiņus un atsvaidzināšanas marķieri, ko var atsaukt.

Vai var apvienot sesijas un JWT?

Jā, tā ir izplatīta prakse: īsa derīguma JWT piekļuves marķieris API izsaukumiem un atsvaidzināšanas marķieris, kas pārvaldīts kā sesija (glabāts un atsaucams servera pusē), lai atjaunotu piekļuves marķieri.