Skip to content
Language:hu Author:Laborci Gergely
identity

Böngészős tárolás és tokenek

Célok

A lecke végére meg tudod különböztetni a böngészős tárolási lehetőségeket (cookie, Web Storage, IndexedDB), el tudod magyarázni, mi a token és mi a JWT, és érted, hogy a token fogalma és a tárolása két külön döntés.

Miért két külön fogalom?

A cookie, a localStorage és az IndexedDB tárolási hely: hova teszünk adatot. A token ezzel szemben egy érték, amelyet egy protokoll meghatározott célra ad át és ellenőriz: hozzáférést vagy azonosítást képvisel. Egy token tárolható cookie-ban, localStorage-ban vagy memóriában, és a döntés a biztonságra is hat. Aki a kettőt összekeveri, rossz kérdést tesz fel: nem az a kérdés, hogy „cookie vagy token”, hanem az, hogy mit akarunk igazolni, és hol őrizzük, hogyan továbbítjuk.

Kurzusoldal, vázlat és hozzáférés

A hallgató nyelvi beállítást választ, félbehagy egy helyi vázlatot, és bejelentkezik. A három adat eltérő célú:

Adat Természetes hely Miért?
Nyelvi beállítás (kicsi) Cookie vagy localStorage Egyszerű, nem érzékeny.
Félbehagyott vázlat (strukturált, nagyobb) IndexedDB Strukturált adat (3.6).
A bejelentkezés igazolása Munkamenet-cookie vagy token Érzékeny; a kezelését biztonsági szempontok határozzák meg.
flowchart TD
    A[Alkalmazási igény] --> C[Cookie: a HTTP-kéréshez magától csatolódhat]
    A --> W[Web Storage: kulcs–érték]
    A --> I[IndexedDB: strukturált adat]
    T[Token: igazolás vagy hozzáférési érték] -. külön tárolási döntés .-> C
    T -. külön tárolási döntés .-> W

Az ábra nem javasolja, hogy érzékeny tokent automatikusan Web Storage-ban tároljunk; csak azt mutatja, hogy a token fogalma és a tárolás helye külön döntés.

A tárolók összehasonlítása

Cookie localStorage sessionStorage IndexedDB
Hatókör domain és útvonal szerint eredet (3.6) eredet + böngészőlap eredet
Kéréssel együtt megy? igen, ha a hatókör egyezik nem nem nem
JavaScript olvashatja? nem, ha HttpOnly igen igen igen
Méret kb. 4 kilobájt / cookie kb. 5 MiB / eredet kb. 5 MiB / eredet böngésző kezeli, nagy
Élettartam Max-Age / Expires a böngésző törlésig a lap bezárásáig a böngésző törlésig

(A méretadatok az MDN oldalai alapján: cookie kb. 4 kilobájt, a Web Storage eredetenként kb. 5 MiB.) Két következmény:

  • A cookie magától csatolódik a kéréshez, ami kényelmes (a munkamenet-azonosítónak ez kell), de azt is jelenti, hogy más oldalról indított kérésekhez is csatolódhat, ha a SameSite ezt nem akadályozza (8. fejezet).
  • A localStorage és az IndexedDB tartalmát bármely, az oldalon futó JavaScript olvashatja. Ha egy támadó szkriptet tud beszúrni az oldalba (XSS, 8. fejezet), elolvashatja az itt tárolt tokent is. A HttpOnly cookie-t a JavaScript nem látja.

A helyi tárolás nem megbízható szerveroldali nyilvántartás és nem szinkronizál a felhasználó többi eszközére. Egy elfogadott jelentkezés hivatalos állapotát a szervernek kell kezelnie.

Mi a token?

A token olyan érték, amelyet egy protokoll meghatározott célra ad át és ellenőriz. Egy hozzáférési token (access token) például egy API-erőforráshoz való hozzáférést képviseli. A szerveroldali munkamenet-azonosító (7.2) is hordozó érték, de más mechanizmushoz kapcsolódik. Az API-k tokent gyakran az Authorization fejlécben fogadnak, Bearer sémával:

GET /jelentkezesek/anna HTTP/1.1
Host: kurzuspont.example
Authorization: Bearer <token>

Az RFC 6750 szerint a „bearer token” birtokosa (a hordozó) használhatja a tokent az erőforráshoz, kriptográfiai kulcs bizonyítása nélkül: a birtoklás maga a jogosultság. Ezért a tokent csak TLS-en szabad továbbítani (az RFC kötelezővé teszi), az URL-be tenni nem tanácsos (az RFC is ellenzi), mert az URL naplókba kerül, és az élettartama legyen rövid.

JWT: egy elterjedt tokenformátum

Nem minden token JWT, és egy JWT sem automatikusan biztonságos. A JWT (JSON Web Token) az RFC 7519 szerint kompakt, URL-biztos formája állítások (claim) továbbításának két fél között. A token három, pontokkal elválasztott, base64url kódolású részből áll: fej (header), tartalom (payload) és aláírás. Kipróbáltuk (Node.js crypto modul, HS256, vagyis HMAC SHA-256 aláírás egy közös titokkal):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhbm5hIiwic3plcmVwIjoiaGFsbGdhdG8iLCJleHAiOjE3OTE3NDE2MDB9._x4fXjw_K5A-qpXUeTODT1aTOQfqua55_Rd0XqhWsSg

fej      : {"alg":"HS256","typ":"JWT"}
tartalom : {"sub":"anna","szerep":"hallgato","exp":1791741600}

eredeti token                 : ÉRVÉNYES aláírás
módosított token (szerep=oktato): ÉRVÉNYTELEN aláírás

Három tanulság:

  1. A tartalom nem titkos. A JWT tartalma bárki által dekódolható (base64url nem titkosítás). Az RFC szerint a JWT lehet aláírt (JWS), titkosított (JWE) vagy akár védetlen. Titkos adatot nem szabad aláírt, de nem titkosított JWT-be tenni.
  2. Az aláírás a sértetlenséget védi. Ha valaki átírja a szerep mezőt, az aláírás már nem egyezik, ezért a szerver elutasítja. A módosítás tehát észrevehető.
  3. A lejárat a tartalomban van (exp, másodperc a Unix-időszámítás kezdetétől), de a szervernek ellenőriznie kell. Ha egy tokent vissza akarunk vonni a lejárat előtt, ahhoz a szerver oldalán is nyilvántartás kell.

A JWT jellemzően „önálló” token: a szerver az aláírásból el tudja dönteni az érvényességét, nem kell hozzá munkamenet-tábla. Ez kényelmes, de a visszavonás nehezebb. A formátum választása a kliens típusától, a hozzáférési határtól és a biztonsági modelltől függ.

Egy webhely küldhet cookie-ban szerveroldali munkamenet-azonosítót. Egy API elfogadhat hozzáférési tokent az Authorization fejlécben. OAuth 2.0 és OpenID Connect környezetben többféle token jelenhet meg, eltérő célra (7.5). A „cookie vagy token” tehát hamis, túl egyszerű választás: a cookie továbbítási és tárolási mechanizmus, a token pedig protokollbeli érték.

Végigvezetett példa: a Kurzuspont belépési tokenje

A Kurzuspontnak van egy mobilalkalmazása is. A böngészős felület munkamenet-cookie-t használ, a mobilalkalmazás hozzáférési tokent küld az Authorization fejlécben.

Kliens Igazolás Tárolás Indok
Böngésző munkamenet-cookie (HttpOnly) a böngésző cookie-tárolója A JavaScript nem éri el, magától csatolódik.
Mobilalkalmazás hozzáférési token az operációs rendszer biztonságos tárolója Nincs cookie-modell; rövid élettartam.

Mindkettőnél a szerver ellenőrzi a jogosultságot (7.4), és az igazolás visszavonható.

Gyakori tévhitek

Állítás Pontosítás
„A token egy böngészős tárhely neve.” Érték; a tárolása külön tervezési döntés.
„Minden token JWT.” Több formátum létezik, köztük átláthatatlan token is.
„A localStorage adatai automatikusan mennek a szervernek.” A cookie-val ellentétben nem csatolódnak a kérésekhez.
„A böngészőben tárolt sikeres jelentkezés a hivatalos eredmény.” A szerveroldali állapot a mérvadó.
„A JWT-ben titkolt az adat.” Az aláírt JWT tartalma bárki számára olvasható.

Röviden

  • A cookie, a Web Storage és az IndexedDB tárolók; a token egy érték, amelynek tárolása külön döntés.
  • A cookie magától csatolódik és lehet HttpOnly; a localStorage tartalmát bármely oldalon futó szkript olvashatja.
  • A bearer token birtoklás alapján működik: TLS, rövid élettartam, URL-ben nem tanácsos küldeni.
  • A JWT aláírt formátum: a tartalom olvasható, de nem módosítható észrevétlenül.

Ellenőrző kérdések

  1. Miért veszélyesebb egy tokent localStorage-ban tartani egy XSS-sebezhető oldalon, mint HttpOnly cookie-ban?
  2. Mit jelent az, hogy a bearer token birtoklása a jogosultság?
  3. Miért olvasható bárki számára egy aláírt JWT tartalma?
  4. Mit véd az aláírás, és mit nem?

Tanulási források

Prerequisites (2)

  • JavaScript
  • alkalmazásállapot

Teaches (2)

  • token
  • JWT