Wie Sie JWT-Token dekodieren und prüfen
JSON Web Tokens (JWTs) sind die häufigste Art, Authentifizierung in modernen Webanwendungen zu handhaben. Wenn bei der Auth etwas schiefgeht, ein Benutzer wird unerwartet ausgeloggt, Berechtigungen sind falsch, eine API gibt 401 zurück, ist das Decodieren des JWT meist der erste Debug-Schritt. Die drei Teile eines JWT zu verstehen, die Standard-Claims, die Algorithmen, mit denen er signiert werden kann, und die häufigen Stolperfallen, verwandelt Auth-Debugging von Voodoo in eine Routineprüfung.
Eine kurze Geschichte des JWT
JWTs wurden im Mai 2015 in RFC 7519 standardisiert, nach mehreren Jahren Draft-Iteration bei der IETF. Das Format borgte sich von früheren Designs kompakter Tokens (SAML-Assertionen, einfache opake Cookies), fügte aber zwei Dinge hinzu, die ihnen fehlten: eine strenge JSON-Form, die in jeder Sprache lesbar war, und eine base64url-sichere Codierung, die URL-Parameter, HTTP-Header und Formularfelder ohne erneutes Escapen überlebte. Die begleitenden Spezifikationen, JWS (RFC 7515) für Signaturen, JWE (RFC 7516) für Verschlüsselung und JWA (RFC 7518) für Algorithmusnamen, bilden zusammen die JOSE-Familie (JavaScript Object Signing and Encryption).
OAuth 2.0 und OpenID Connect übernahmen JWT bald darauf als Standard-Token-Format, weshalb fast jeder moderne Auth-Anbieter (Auth0, Okta, Cognito, Keycloak, Firebase, Supabase, Clerk) sie heute ausstellt. Die Kombination aus selbstenthaltenden Tokens und zustandslosen Backends erwies sich als sehr natürliche Passform für Microservices und API-Gateways. Der Nachteil ist, dass JWTs notorisch leicht missbraucht werden, und das letzte Jahrzehnt hat einen stetigen Strom von CVEs in Bibliotheken hervorgebracht, die den Algorithmus nicht sorgfältig validierten.
Was in einem JWT steckt
Ein JWT hat drei Teile, durch Punkte getrennt:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U
Header: enthält den Algorithmus (HS256, RS256 usw.) und den Tokentyp.
{"alg": "HS256", "typ": "JWT"}
Payload: enthält Claims (Datenaussagen) über Benutzer und Token.
{"sub": "1234567890", "name": "Alice", "exp": 1700000000}
Signatur, ein kryptografischer Hash, der bestätigt, dass das Token nicht manipuliert wurde. Sie können sie ohne den Signaturschlüssel nicht lesen.
Jeder Abschnitt ist base64url-codiert, was bedeutet, er verwendet - und _ statt + und / und lässt das abschließende =-Padding weg. Base64url ist keine Verschlüsselung; nur den mittleren Abschnitt in einen beliebigen Decoder einzufügen, offenbart die Payload. Das ist Absicht: Mittlere Abschnitte sind dafür gedacht, von Diensten auf dem Weg gelesen zu werden, die Signatur ist der einzige Teil, der Authentizität beweist.
Häufige JWT-Claims
Standard-Claims sind bei IANA registriert und in RFC 7519 definiert. Die meisten sind optional, aber die unten sind fast immer vorhanden.
| Claim | Voller Name | Was er enthält |
|---|---|---|
sub | Subject | Benutzer-ID oder Identifikator |
exp | Expiration (Ablauf) | Unix-Timestamp, wann das Token abläuft |
iat | Issued At (ausgestellt am) | Unix-Timestamp der Token-Erstellung |
iss | Issuer (Aussteller) | Wer das Token erstellt hat (Ihr Auth-Server) |
aud | Audience (Publikum) | Für wen das Token gedacht ist |
nbf | Not Before (nicht vor) | Token ist vor dieser Zeit nicht gültig |
jti | JWT ID | Eindeutiger Token-Identifikator |
azp | Authorized Party | Die Partei, an die das Token ausgegeben wurde (OIDC) |
scope / scp | OAuth-Scopes | Gewährte Berechtigungen, oft leerzeichengetrennt |
email | Standard-OIDC-Benutzeridentifikator | |
name | Name | Anzeigename (OIDC) |
nonce | Nonce | OIDC-Replay-Schutzwert |
kid (Header) | Key ID | Welcher Signaturschlüssel verwendet wurde (für JWKS-Lookup) |
Über den Standardsatz hinaus fügen Anwendungen ihre eigenen Custom-Claims hinzu (roles, tenant_id, feature_flags, permissions). Custom-Claim-Namen haben standardmäßig keinen Namespace, was bedeutet, dass zwei verschiedene Dienste denselben Namen verwenden können, um Unterschiedliches zu meinen; die OIDC-Konvention, mit einer URI zu präfixieren (https://myapp.com/roles), vermeidet die Kollision.
So decodieren Sie ein JWT
- Fügen Sie Ihr Token ein: Geben Sie das vollständige JWT (header.payload.signature-Format) in den Decoder ein. Browser-basierte Decoder verarbeiten es lokal, das Token verlässt nie die Seite.
- Sehen Sie die decodierten Abschnitte: Das Tool zeigt Header (Algorithmus), Payload (Claims) und Signatur als formatiertes JSON an, mit Zeitstempeln sowohl als Unix-Ganzzahl als auch als lesbares Datum.
- Prüfen Sie die Claims: Untersuchen Sie Ablaufzeit, Aussteller, Subjekt, Publikum und alle Custom-Claims, die Ihre Autorisierungslogik antreiben.
- Vergleichen Sie mit Erwartungen: Gleichen Sie den Aussteller mit dem konfigurierten Auth-Anbieter ab, das Publikum mit der API, an die das Token gesendet wird, und alle Rollen-/Scope-Claims mit den Berechtigungen, die der Benutzer haben sollte.
- Zeitreise-Test: Fahren Sie mit dem Mauszeiger über
iat,nbfundexp, um zu sehen, ob das Token derzeit gültig ist, bald abläuft oder so lange her ausgestellt ist, dass Ihre Uhrabweichungstoleranz es nicht mehr abdeckt.
Signaturalgorithmen
Nicht alle JWTs verwenden dieselbe Krypto. Der alg-Header sagt Ihnen, zu welcher Familie die Signatur gehört, und jede hat sehr unterschiedliche Sicherheitseigenschaften.
| Algorithmus | Familie | Schlüsseltyp | Wann wählen |
|---|---|---|---|
HS256 | HMAC | Geteiltes Geheimnis | Single-Service-Apps; teilen Sie das Geheimnis nie zwischen Teams |
HS384 / HS512 | HMAC | Geteiltes Geheimnis | Wie HS256 mit längeren Digests |
RS256 | RSA | Öffentliches/privates Schlüsselpaar | Am häufigsten bei OIDC; Verifizierer brauchen nur den öffentlichen Schlüssel |
RS384 / RS512 | RSA | Schlüsselpaar | Wie RS256 mit größeren Schlüsseln |
PS256 / PS384 / PS512 | RSA-PSS | Schlüsselpaar | Modernes RSA, für neue Deployments gegenüber RS empfohlen |
ES256 / ES384 / ES512 | ECDSA | Elliptische-Kurven-Schlüsselpaar | Kleinere Schlüssel als RSA, schnellere Verifikation |
EdDSA | Ed25519 | Edwards-Kurven-Schlüsselpaar | Neuestes, kleinstes, schnellstes; noch nicht universell |
none | Keiner | Keiner | In Produktion verboten; einige alte Bibliotheken akzeptieren es noch |
Asymmetrische Algorithmen (RS*, PS*, ES*, EdDSA) erlauben jedem Dienst, ein Token nur mit einem öffentlichen Schlüssel zu verifizieren, weshalb sie OIDC dominieren. Symmetrisch (HS*) ist innerhalb einer einzigen Anwendung in Ordnung, wird aber zum Albtraum, wenn Sie es über mehrere Konsumenten rotieren oder verteilen müssen.
Debuggen mit JWTs
Token abgelaufen? Prüfen Sie den exp-Claim. Wandeln Sie den Unix-Timestamp in ein lesbares Datum um. Liegt er in der Vergangenheit, ist das Token abgelaufen und muss erneuert werden. Die meisten JWT-Bibliotheken lehnen abgelaufene Tokens standardmäßig ab; akzeptiert Ihre App sie, ist das ein Sicherheitsbug.
Falsche Berechtigungen? Suchen Sie nach Rollen- oder Scope-Claims in der Payload. Sie variieren nach Implementierung, sehen aber oft aus wie "role": "admin" oder "scope": "read write profile".
Benutzeridentitätsprobleme? Der sub-Claim identifiziert den Benutzer. Prüfen Sie, ob er der erwarteten Benutzer-ID entspricht. Beachten Sie, dass einige Anbieter opake GUIDs verwenden, andere E-Mail-Adressen; der Decoder zeigt Ihnen genau, was drin ist.
Token nicht akzeptiert? Prüfen Sie den aud-Claim (Publikum). Erwartet die API einen spezifischen Audience-Wert und das Token hat einen anderen, wird es abgelehnt. Audience-Diskrepanzen sind ein häufiges Symptom dafür, dass ein Token an den falschen Dienst geroutet wurde.
401-Fehler nach Deploy? Prüfen Sie den iss-Claim (Aussteller). Ein neuer Auth-Anbieter-Tenant oder ein ausgetauschter Signaturschlüssel ändert die Aussteller-URL; vertraut Ihr Verifizierer immer noch der alten, sehen alle Tokens ungültig aus.
Uhrabweichungsprobleme? Liegt iat leicht in der Zukunft oder exp leicht in der Vergangenheit, kann die Uhr Ihres Servers driften. Die meisten JWT-Bibliotheken erlauben ein paar Sekunden Spielraum; sonst behebt eine NTP-synchronisierte Uhr das Problem.
Häufige Fallstricke
- Dem
alg-Header ohne Allow-List vertrauen, die klassische JWT-Schwachstelle war, dass ein Server jeden Algorithmus akzeptierte, den das Token zu verwenden behauptete. Ein Token mitalg: none(keine Signatur) oderalg: HS256(mit Ihrem öffentlichen Schlüssel als Geheimnis signiert) konnte jede Payload fälschen. Pinnen Sie den Verifizierer auf den exakt erwarteten Algorithmus. - Geheimnisse in die Payload legen, die Payload ist base64url-codiert, nicht verschlüsselt. Jeder mit dem Token kann sie lesen. Niemals Passwörter, API-Schlüssel oder etwas einfügen, das Sie nicht in einen Query-String stellen würden.
- Langlebige Tokens ohne Widerruf, ein 30-Tage-JWT kann ohne Token-Blacklist oder Session-Store nicht widerrufen werden. Halten Sie Zugriffstokens kurz (5-60 Minuten) und verwenden Sie für längere Sitzungen einen Refresh-Token-Flow.
- Uhrabweichung vergessen, Server in verschiedenen Zeitzonen oder mit driftenden Uhren lehnen Tokens ab, die gültig sein sollten. Erlauben Sie 30-60 Sekunden Spielraum bei
expundnbf. - Aussteller ohne Verifikation vertrauen, der
iss-Claim ist Teil der Payload, die jeder schreiben kann. Zu verifizieren, dass sein Wert dem konfigurierten Aussteller entspricht, ist erforderlich; ihn in einer Allow-List zu führen verhindert, dass ein Angreifer Tokens prägt, die vorgeben, von Ihrem Anbieter zu kommen. - HS256-Geheimnisse über Umgebungen wiederverwenden, dasselbe Geheimnis in Dev und Prod bedeutet, dass ein geleaktes Dev-Token in der Produktion funktioniert. Verwenden Sie Schlüssel pro Umgebung, idealerweise aus einem Secret-Manager.
- Tokens im localStorage speichern, localStorage ist von jedem JavaScript lesbar, ein einziger XSS-Bug exfiltriert die Tokens aller Benutzer. HttpOnly-Cookies mit SameSite=Lax (oder Strict) sind die sicherere Voreinstellung.
- Vollständige Tokens loggen, Anwendungslogs, die vollständige JWTs erfassen, leaken die Tokens an jeden mit Logzugriff. Auf die ersten 10 Zeichen kürzen oder nur die
jtiloggen. kid-Rotation ignorieren, wenn ein Anbieter Signaturschlüssel rotiert, haben die neuen Tokens einen neuenkid-Header. Ein Verifizierer, der die JWKS ewig cached, beginnt gültige Tokens abzulehnen. Bei Key-ID-Fehlschlag das JWKS neu abrufen.- JWT inkonsistent mit Sessions mischen, manche Endpunkte hinter JWT, andere hinter Cookie-Sessions, führt zu Bugs, bei denen ein eingeloggter Benutzer auf einer Route unauthentifiziert erscheint. Pro Dienst ein Modell wählen.
Alternativen zu JWT
JWT ist dominant, aber nicht die einzige Option. Jede Alternative tauscht andere Eigenschaften aus.
| Mechanismus | Stärke | Schwäche |
|---|---|---|
| JWT (JWS) | Selbstenthalten, einfach über Dienste | Ohne zusätzlichen Zustand nicht widerrufbar |
| Opake Tokens + Introspektion | Einfach widerrufbar, verbirgt Claims | Jede Anfrage trifft den Auth-Server |
| Serverseitige Sessions | Einfachstes Modell, sofortiger Widerruf | Schwer über Dienste zu skalieren |
| PASETO | Sicherere JWT-Ablösung (keine alg-Verwirrung) | Kleineres Ökosystem |
| Macaroons | Eingebaute Attenuation (delegierte Rechte) | Begrenzte Bibliotheksunterstützung |
| OAuth 2.0 + JWT-Zugriffstokens | Industriestandard für APIs | Spezifikation groß, leicht falsch zu implementieren |
| OIDC-ID-Tokens | Standard-Benutzeridentität + JWT | Oft mit Zugriffstokens verwechselt |
| mTLS-Client-Zertifikate | Stärkste Auth auf der Transportschicht | Verwaltungsaufwand für Zertifikate |
Für die meisten Teams steht die Wahl zwischen JWT und opaken Tokens. JWT gewinnt, wenn die Verifikation billig und offline sein muss; opake Tokens gewinnen, wenn Widerruf sofort sein muss.
Datenschutz und der Decoder
Der JWT-Decoder läuft vollständig in Ihrem Browser. Das Token, das Sie einfügen, wird geteilt, base64url-decodiert, und das JSON wird ohne jegliche Netzwerkanfrage geparst und schön formatiert. Es gibt kein Log der decodierten Tokens, keine Analytik zu den Claims, die sie enthalten, und keine Möglichkeit für irgendjemanden, zu rekonstruieren, wofür Sie debuggt haben. JWTs enthalten oft Benutzeridentifikatoren, E-Mail-Adressen, interne Rollennamen und Tenant-IDs, genau die Art von Metadaten, die Sie nicht an den Server eines Fremden senden möchten. Clientseitig zu decodieren hält diese Information auf Ihrer Maschine, was die richtige Voreinstellung für jede Debug-Aufgabe ist, die Authentifizierung berührt.
Häufig gestellte Fragen
Kann ich eine JWT-Signatur mit einem Decoder überprüfen?
Nein. Die Signaturprüfung erfordert das Signaturgeheimnis oder den öffentlichen Schlüssel, die auf Ihrem Server liegen. Ein Decoder zeigt Ihnen, was im Token steckt, doch die kryptografische Prüfung muss in Ihrem Backend erfolgen. Vertrauen Sie in Produktion nie einem unverifizierten JWT.
Ist es sicher, ein JWT in ein Online-Tool einzufügen?
Ja, wenn das Tool im Browser läuft. Browserbasierte Decoder verarbeiten das Token lokal, nichts wird an einen Server gesendet. Vermeiden Sie Tools, die Netzwerkanfragen mit Ihrem Token machen.
Was ist der exp-Claim?
Der exp-Claim (Expiration) ist ein Unix-Timestamp, der angibt, wann das Token abläuft. Nach diesem Zeitpunkt sollte es abgelehnt werden. Prüfen Sie diesen Claim immer beim Debuggen von Authentifizierungsproblemen.
Können JWTs verschlüsselt werden?
Standard-JWTs (JWS) sind signiert, aber nicht verschlüsselt, jeder kann den Payload dekodieren. JWE-Token (JSON Web Encryption) sind verschlüsselt, aber weniger verbreitet. Geben Sie nie sensible Daten (Passwörter, Geheimnisse) in einen Standard-JWT-Payload.
What is the alg none vulnerability?
Early JWT libraries accepted tokens with an alg header set to "none", meaning the signature could be omitted entirely. An attacker who set this header could forge any payload. Modern libraries reject "none" by default, but legacy systems may still be exposed; always allow-list the expected algorithm rather than trusting the header.
How should I store a JWT on the client?
HttpOnly secure cookies with SameSite=Lax (or Strict) are the safest default; they cannot be read by JavaScript, which mitigates XSS token theft. localStorage is convenient but vulnerable to any XSS bug. Never store long-lived JWTs alongside untrusted scripts.