JSON Web Tokens werden häufig als „Login-Token“ beschrieben. Das greift zu kurz. Ein JWT ist zunächst ein kompaktes Format, das Aussagen über ein Subjekt transportiert und kryptografisch gegen unbemerkte Veränderung schützen kann. Ob es für Authentifizierung, einen einmaligen Vorgang oder den Austausch zwischen Diensten geeignet ist, entscheidet das umgebende Protokoll. Das Format allein kennt weder Logout noch Benutzerrechte noch eine sichere Speicherstrategie im Browser.

Ein typisches JWT besteht aus drei Segmenten

Die verbreitete signierte Form, genauer ein JWS, enthält Header, Payload und Signatur. Alle drei Abschnitte sind durch Punkte getrennt. Header und Payload werden als JSON serialisiert und mit Base64URL dargestellt. Die Signatur schützt die konkrete codierte Zeichenfolge aus den ersten beiden Segmenten.

Base64URL ist lesbar und umkehrbar. Wer ein Token besitzt, kann Header und Payload ohne Schlüssel decodieren. Vertrauliche Daten gehören deshalb nicht allein aufgrund der Signatur in diese Claims. Für verschlüsselte Tokens existiert JWE, doch auch dann müssen Schlüssel, Algorithmen und Lebenszyklus korrekt gestaltet werden.

Der Header beschreibt die kryptografische Verarbeitung

Im Header steht typischerweise ein Algorithmus wie RS256 oder ES256. Ein kid kann angeben, welcher Schlüssel zur Verifikation gedacht ist. Der Verifier darf diese Angaben nicht blind als Policy übernehmen. Er muss selbst festlegen, welche Algorithmen und Schlüssel für den jeweiligen Issuer erlaubt sind.

Ein Schlüssel-Identifier ist ein Auswahlhinweis, keine frei nutzbare URL oder Datenbankanweisung. Unsichere Implementierungen haben Werte daraus für Dateipfade, SQL oder ungeprüfte Netzwerkrequests verwendet. Bibliothek und Anwendung müssen die Eingabe gegen einen bekannten Schlüsselsatz auflösen.

Claims tragen die Aussagen des Tokens

Der Payload enthält registrierte Claims wie Issuer iss, Audience aud, Subject sub, Ablaufzeit exp und Not-before nbf. Dazu kommen anwendungsspezifische Angaben, etwa Tenant oder Rollen. Jede dieser Aussagen braucht eine definierte Semantik.

Ein gültiges JSON und eine korrekte Signatur reichen nicht. Ein Token für einen anderen Dienst, einen anderen Mandanten oder einen vergangenen Zeitpunkt muss abgelehnt werden. Der Consumer validiert alle Claims, die seinen Vertrauenskontext bestimmen.

Die Signatur bindet Inhalt und Aussteller

Bei HMAC verwenden Aussteller und Verifier dasselbe Geheimnis. Jeder, der verifizieren kann, kann damit auch neue Tokens signieren. Asymmetrische Verfahren trennen diese Rollen: Der Issuer besitzt den privaten Schlüssel, während Dienste nur den öffentlichen Schlüssel benötigen.

Die Signatur beweist nicht automatisch, dass eine Person aktuell angemeldet oder berechtigt ist. Sie zeigt, dass die geschützten Bytes von einer Partei mit dem passenden Schlüssel stammen und unverändert sind. Ob diese Partei vertrauenswürdig ist und welche Claims akzeptiert werden, bleibt Konfiguration.

Die exakten Bytes sind entscheidend

Zwei JSON-Objekte können dieselben Eigenschaften in anderer Reihenfolge oder mit anderem Whitespace enthalten. Nach der Serialisierung entstehen dennoch andere Bytes und damit andere Signaturen. Ein Verifier darf die Segmente nicht decodieren, neu formatieren und anschließend über die neue Darstellung prüfen.

Standardbibliotheken verifizieren die empfangene Signing Input korrekt. Eigene Implementierungen sind riskant, weil Base64URL, Algorithmusparameter und Signaturformate zahlreiche Details besitzen.

Ablaufzeiten begrenzen nur die Zukunft

exp legt fest, ab wann ein Token nicht mehr akzeptiert werden soll. nbf verhindert eine zu frühe Nutzung, iat beschreibt typischerweise den Ausgabezeitpunkt. Kleine Clock-Skews zwischen Systemen können mit einer begrenzten Toleranz berücksichtigt werden.

Eine lange Ablaufzeit macht gestohlene Tokens lange brauchbar. Eine sehr kurze Zeit erhöht Erneuerungsverkehr und Komplexität. Access Tokens und langlebigere Refresh Tokens sollten unterschiedliche Aufgaben, Speicherorte und Widerrufsregeln besitzen.

Audience verhindert die Nutzung beim falschen Dienst

Ein Token kann korrekt signiert sein und trotzdem nicht für den aktuellen API-Service bestimmt sein. Der Audience-Claim benennt den erwarteten Empfänger. Ohne Prüfung könnte ein weniger privilegierter Dienst ein Token erhalten, das ein anderer Dienst mit höherer Wirkung akzeptiert.

Issuer und Audience bilden gemeinsam eine Vertrauensbeziehung. Ein Verifier muss den erwarteten Issuer kennen, dessen Schlüssel kontrolliert beziehen und nur die für diesen Endpoint passende Audience zulassen.

Schlüsselrotation braucht überlappende Gültigkeit

Ein Issuer wechselt regelmäßig oder nach einem Vorfall seinen Signaturschlüssel. Neue Tokens verwenden den neuen Schlüssel, während noch nicht abgelaufene alte Tokens mit dem vorherigen öffentlichen Schlüssel geprüft werden müssen. Ein kid hilft bei dieser Auswahl.

Schlüsselsets werden häufig gecacht. Der Cache braucht eine kontrollierte Aktualisierung, wenn ein unbekannter Identifier erscheint, aber darf nicht durch beliebige Tokenwerte zu unbegrenzten Netzwerkrequests gezwungen werden. Entfernung alter Schlüssel muss zur maximalen Tokenlebensdauer passen.

JWT ist nicht automatisch zustandslos

Eine API kann ein Token ohne Datenbankzugriff verifizieren. Trotzdem benötigt das Gesamtsystem oft Zustand: Refresh Tokens, Benutzerdeaktivierung, Schlüsselrotation, Consent, Sessionübersicht und Widerruf. „Stateless“ beschreibt höchstens einen Teil des Request-Pfads.

Wer sofortigen Logout oder Rechteentzug verlangt, muss kurze Access-Token-Laufzeiten, eine Revocation-Liste oder einen zusätzlichen Statuscheck einplanen. Das verschiebt die Architektur näher an serverseitige Sitzungen, was je nach Produkt vollkommen sinnvoll sein kann.

Transport und Speicherung bestimmen das Diebstahlrisiko

Im Browser kann ein Token in einem HttpOnly-Cookie liegen oder von JavaScript verwaltet werden. JavaScript-zugänglicher Storage ist bei XSS exponiert. Cookies werden automatisch gesendet und brauchen deshalb passende SameSite- und CSRF-Schutzentscheidungen.

Es gibt keine universelle Empfehlung, ein JWT stets in Local Storage oder stets in Cookies zu speichern. Entscheidend sind Bedrohungsmodell, Clienttyp und Tokenfunktion. In jedem Fall gehören Tokens nicht in URLs, weil diese in History, Logs und Referrern auftauchen.

Claims altern während der Tokenlaufzeit

Eine Rolle im Token ist eine Momentaufnahme. Wird ein Benutzer gesperrt oder verliert eine Berechtigung, bleibt der alte Claim bis zum Ablauf gültig, sofern kein weiterer Kontrollmechanismus existiert. Je dynamischer und kritischer eine Berechtigung ist, desto ungeeigneter ist ein langlebiger eingebetteter Zustand.

Tokens sollten klein bleiben und nur Claims tragen, die der Consumer wirklich benötigt. Profile, große Berechtigungslisten oder häufig wechselnde Daten können über eine aktuelle Quelle geladen werden.

JWT ist ein Baustein, kein vollständiges Auth-System

Ein belastbares System definiert Aussteller, Empfänger, Algorithmus-Allowlist, Schlüsselbezug, Claim-Prüfung, Laufzeiten, Speicherung und Vorfallreaktion. Es verwendet gepflegte Bibliotheken und testet abgelaufene, verfrühte, falsch adressierte und mit unbekannten Schlüsseln signierte Tokens.

Richtig eingesetzt ist JWT eine praktische, interoperable Hülle für signierte Aussagen. Falsch verstanden wird es zu einem sichtbaren Datencontainer, dem zu viel Vertrauen zugeschrieben wird. Die Sicherheit entsteht aus dem gesamten Vertrag um das Token.