JWT vs munkamenet: melyik hitelesítési mechanizmust válasszuk?
A felhasználó hitelesítése azt jelenti, hogy minden kérésnél tudjuk, ki ő. Két nagy család verseng: a szerveroldali munkamenetek, ahol a szerver nyilvántartja a bejelentkezett felhasználót, és a JSON Web Tokenek (JWT), ahol az identitás egy aláírt tokenben utazik, amelyet a kliens hordoz. A választás befolyásolja a biztonságot, a terhelhetőséget és a felhasználó kijelentkeztetésének egyszerűségét. Íme, hogyan döntsünk a környezet alapján.
A szerveroldali munkamenetek (állapottal)
Munkamenet esetén a szerver bejelentkezéskor létrehoz egy munkamenet-azonosítót, a kapcsolódó adatokat (identitás, szerepek, kosár) a szerver oldalon tárolja (memória, Redis, adatbázis), és a böngészőnek egy sütit küld vissza, amely csak ezt az azonosítót tartalmazza. Minden kérésnél a szerver elolvassa a sütit, megtalálja a munkamenetet, és tudja, ki beszél.
- Szerveroldali állapot: az igazság forrása a szerveren marad, a kliens csak egy átlátszatlan hivatkozást hordoz.
- Azonnali visszavonás: a munkamenet szerveroldali törlése azonnal kijelentkezteti a felhasználót.
- Süti: a böngésző automatikusan továbbítja, ideális esetben
HttpOnly,SecureésSameSitebeállítással.
A JSON Web Tokenek (állapot nélkül)
A JWT egy önhordó token, amely három base64url kódolású, pontokkal elválasztott részből áll: egy header, egy payload (a claimek, például a felhasználó azonosítója és a lejárat) és egy aláírás. A szerver bejelentkezéskor aláírja a tokent; ezután elég ellenőriznie az aláírást, hogy megbízzon a tartalomban, anélkül, hogy bármit tárolnia kellene.
- Állapot nélküli: minden szükséges információ a tokenben van, a szervernek nincs szüksége megosztott memóriára.
- Mindenhol ellenőrizhető: bármely szolgáltatás, amely ismeri a kulcsot, érvényesítheti a tokent, ami praktikus elosztott architektúrákhoz és SSO-hoz.
- Eszközök: a tokent megvizsgálhatja a JWT dekódolóval, ellenőrizheti az aláírását a JWT ellenőrzővel, vagy létrehozhat egyet a JWT generátorral.
Összehasonlító táblázat
| Szempont | Szerveroldali munkamenet | JWT |
|---|---|---|
| Állapot | Állapottal (szerveren tárolva) | Állapot nélkül (a kliens hordozza) |
| Szerveroldali tárolás | Szükséges (Redis, adatbázis) | Semmilyen |
| Visszavonás | Azonnali | Nehéz lejárat előtt |
| Vízszintes skálázhatóság | Megosztott tároló szükséges | Natív |
| Továbbított méret | Kicsi (egy azonosító) | Nagyobb (aláírt claimek) |
| Tartományok közötti / SSO | Korlátozó | Megfelelő |
| XSS felület | Alacsony HttpOnly sütivel | Magas, ha localStorage-ban tárolt |
Biztonság: XSS, CSRF és visszavonás
Mindkét megközelítés biztonságos, ha jól van megvalósítva, de a kockázataik eltérnek.
- XSS: egy
HttpOnlymunkamenet-süti hozzáférhetetlen a JavaScript számára, ezért védett az injektálással történő lopástól. EgylocalStorage-ban tárolt JWT ezzel szemben bármely szkript által olvasható, ami kiváló célponttá teszi. A JWTHttpOnlysütiben való tárolása megszünteti a JWT ezen előnyét, de újra bevezeti a CSRF kockázatot. - CSRF: a sütik automatikusan elküldődnek, ezért védelem nélkül sebezhetők a CSRF-fel szemben (
SameSiteattribútum, anti-CSRF token). Egy azAuthorizationfejlécben kézzel küldött JWT-t ez nem érint. - Visszavonás: ez a JWT gyenge pontja. Mivel önhordó, nem érvényteleníthető a lejárata előtt anélkül, hogy újra bevezetnénk egy szerveroldali állapotot (visszavonási lista, feketelista). Egy munkamenet azonnal törölhető.
Skálázhatóság és architektúra
Egyetlen szerveren a munkamenetek triviálisak. Amint több példányra osztja el a terhelést, minden példánynak hozzá kell férnie a munkamenetekhez: megosztott tárolóra (Redis) vagy sticky sessionre van szükség. A JWT itt ragyog, mert bármely példány érvényesíti a tokent hálózati hívás vagy közös tárolás nélkül.
- Mikroszolgáltatások: egy JWT az identitást egyik szolgáltatásról a másikra terjeszti központi adatbázis nélkül.
- Nyilvános és mobil API-k: a JWT elkerüli a sütik kezelését a natív kliens oldalán.
- Klasszikus monolit: a munkamenet alapértelmezetten egyszerűbb és biztonságosabb marad.
Mikor melyiket válasszuk
Válassza a munkameneteket, ha
- Klasszikus webalkalmazást fejleszt szerveroldali rendereléssel
- Az azonnali visszavonás kritikus (bank, egészségügy, back-office)
- A legbiztonságosabb alapértelmezett megoldást szeretné, a legkevesebb csapdával
- Az infrastruktúrája gond nélkül elbír egy megosztott munkamenet-tárolót
Válassza a JWT-t, ha
- Olyan API-t tesz közzé, amelyet SPA-k, mobil vagy harmadik felek használnak
- Mikroszolgáltatás-architektúrája vagy tartományok közötti SSO-ja van
- Vízszintesen kell skáláznia megosztott tároló nélkül
- Elfogadja a rövid lejárat és a tokenek frissítésének kezelését
Ajánlás
A legtöbb webalkalmazás esetében a szerveroldali munkamenetek maradnak a legbiztonságosabb és legegyszerűbb választás: azonnali visszavonás, HttpOnly süti és semmilyen tokenkezelés a kliens oldalán. Tartsa fenn a JWT-t azokra az esetekre, ahol az állapotnélkülisége valódi értéket hoz: állapot nélküli API, mobil, mikroszolgáltatások, SSO.
Ha a JWT-t választja, tartson fenn rövid élettartamot (néhány perc), egy HttpOnly sütiben tárolt refresh tokennel párosítva, és gondoskodjon visszavonási listáról az érzékeny esetekre. Így mindkét világ legjobbját kombinálja.
Gyakori kérdések
Titkosított-e egy JWT?
Nem, alapértelmezetten egy JWT csak aláírt, nem titkosított. A payloadja base64url kódolású, és bárki számára olvasható, aki elfogja. Soha ne helyezzen érzékeny adatokat olvasható formában egy JWT-be. A tartalom titkosításához a JWE-hez (JSON Web Encryption) kell folyamodni.
Hol tároljunk egy JWT-t a kliens oldalán?
A legbiztonságosabb egy HttpOnly, Secure és SameSite süti, amely véd az XSS-sel történő lopástól. A localStorage egyszerűbb, de minden rosszindulatú szkriptnek kiteszi a tokent. Kerülje a magas jogosultságú tokenekhez.
Hogyan jelentkeztessünk ki egy felhasználót JWT-vel?
Mivel a token önhordó, a valódi kijelentkezés vagy a lejáratának megvárását, vagy egy szerveroldali visszavonási lista fenntartását igényli. Ezért használnak rövid élettartamokat és egy refresh tokent, amely viszont visszavonható.
Kombinálható-e a munkamenet és a JWT?
Igen, ez bevett gyakorlat: egy rövid élettartamú JWT access token az API-hívásokhoz, és egy munkamenetként kezelt refresh token (szerveroldalon tárolt és visszavonható) az access token megújításához.