jwtdecoder.de

Ratgeber · JWT 2026

JWT im Browser sicher speichern

localStorage ist XSS-anfällig, httpOnly-Cookies sind XSS-sicher aber CSRF-relevant. Empfehlung: Cookie + SameSite=Strict + CSRF-Token.

Foto von Jan-Tristan Rudat

Von Jan-Tristan Rudat

Redakteur jwtdecoder.de

Drei Optionen, alle mit Trade-offs

Wer JWT-basierte Auth im Browser implementiert, muss entscheiden: wo wohnt der Token? Drei Standard-Optionen, je mit Sicherheits-Trade-off.

Option 1: localStorage

localStorage.setItem('access_token', token);
const t = localStorage.getItem('access_token');
fetch('/api/data', { headers: { Authorization: 'Bearer ' + t } });

Vorteile: einfach, persistent über Page-Reloads, kein Server-Setup nötig.

Nachteil: XSS-anfällig. Jeder JavaScript-Code der Origin kann localStorage lesen. Wenn ein Angreifer XSS einschleust (third-party-Script, dependency-Vulnerability, Markdown-Renderer-Bug), kann er den Token klauen und exfiltrieren.

Empfehlung: NIE für Refresh-Tokens. Für kurzlebige Access-Tokens (≤ 15 min) noch akzeptabel, wenn XSS-Hardening sonst stimmt.

Option 2: sessionStorage

Wie localStorage, nur dass der Token mit dem Tab geschlossen wird. Gleiches XSS-Problem. sessionStorage ist auch nicht "sessionStorage = Server-Session"-sicher - der Name ist irreführend, es ist nur "Per-Tab-localStorage".

Empfehlung: selten sinnvoll. Wer Persistenz nicht will, kann den Token einfach in JavaScript-Memory halten (siehe Option 4).

Option 3: httpOnly-Cookie

// Server-Response
Set-Cookie: access_token=eyJhbGc...;
            HttpOnly;
            Secure;
            SameSite=Strict;
            Path=/;
            Max-Age=900

Vorteile:

  • HttpOnly: JavaScript kann nicht zugreifen → XSS-sicher
  • Secure: nur über HTTPS
  • SameSite=Strict: nicht von cross-origin Sites mitgesendet → CSRF-Schutz
  • Browser sendet Cookie automatisch bei jedem Request - kein JS-Code für Header-Setting nötig

Nachteil:

  • CSRF-Relevanz: bei SameSite=Lax oder None müssen CSRF-Tokens zusätzlich gesetzt werden
  • Subdomain-Komplikationen: api.example.com vs www.example.com brauchen sorgfältiges Domain-Cookie-Setup
  • CORS: bei Cross-Origin-API muss credentials: 'include' gesetzt sein, Server CORS-Config muss stimmen

Empfehlung: Default-Wahl für Refresh-Tokens. Auch für Access-Tokens gut, wenn die Same-Origin-Anforderung erfüllt ist.

Option 4: JS-Memory (in-app Variable)

// React-Beispiel
const [accessToken, setAccessToken] = useState(null);
// nach Login:
setAccessToken(receivedToken);
// bei Logout oder Page-Reload: weg

Vorteile: kein XSS-Persistenz-Vektor (Token überlebt Page-Reload nicht), beste Sicherheit für Access-Tokens.

Nachteil: nach Page-Reload weg. User muss sich neu einloggen - außer es gibt einen Refresh-Token im httpOnly-Cookie, der den Access-Token wiederherstellen kann.

Empfehlung: ideale Wahl für kurzlebige Access-Tokens in Kombination mit httpOnly-Cookie für Refresh-Token.

Empfohlene Architektur

Token-TypStorageBegründung
Access-Token (5-15 min)JS-MemoryXSS-Schaden minimal (kurze Lifetime), nicht persistent
Refresh-Token (7-30 Tage)httpOnly + Secure + SameSite=Strict CookiePersistent UND XSS-sicher

Beim Page-Reload: kein Access-Token, aber Refresh-Cookie wird automatisch mitgesendet. Client ruft /token auf, bekommt neuen Access-Token, läuft weiter.

Anti-Pattern: Token aus Cookie in JS auslesen

// FALSCH: extrahiere JWT aus document.cookie und nutze in Header
const token = document.cookie.match(/access_token=([^;]+)/)[1];
fetch('/api', { headers: { Authorization: 'Bearer ' + token } });

Das geht nur, wenn der Cookie NICHT httpOnly ist. Aber dann ist der XSS-Schutz weg.

Anti-Pattern: zwei Locations gleichzeitig

Manche Setups speichern den Token sowohl in Cookie als auch in localStorage. "Belt and suspenders". Tatsächlich: das schlechtere von beiden Welten - XSS klaut aus localStorage, CSRF nutzt den Cookie.

Mobile-Apps

iOS Keychain bzw. Android Keystore sind die richtigen Storage-Layer für Mobile. Bei Hybrid-Apps (Cordova, Capacitor, React Native): Plugin nutzen, das Native-Storage ansteuert. Nicht localStorage in einer WebView.

Kontroverse: localStorage ist "OK" für viele Sites

Manche Security-Experten argumentieren, dass XSS-Hardening sowieso Pflicht ist (Content-Security-Policy, sanitization, dependency-audit) und die Diskussion um localStorage vs Cookie eine Ablenkung sei. Auch korrekt: wenn XSS möglich ist, kann ein Angreifer auch ohne Token klauen einfach im User-Context handeln.

Aber: Defense-in-Depth. httpOnly-Cookie ist eine zusätzliche Verteidigungsschicht, kostenlos im Setup. Es gibt keinen guten Grund, sie wegzulassen.

Im JWT Decoder wird kein Token irgendwo gespeichert - alles passiert clientseitig in JavaScript-Memory, weg nach Page-Reload.

Mehr zum Thema