Dekodieren in einem Schritt
Ein JSON Web Token sieht so aus: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMifQ.signatur, also drei Base64url-Zeichenketten, die durch Punkte verbunden sind. Jedes JWT beginnt mit eyJ, weil die Zeichen {" in Base64 genau so aussehen.
Füge das Token in das Tool unten ein. Ein Präfix Bearer, das du aus einem Authorization-Header mitkopiert hast, ist kein Problem. Du siehst Header und Payload als formatiertes JSON, die Claims exp, iat, nbf und auth_time als Datum in deiner Ortszeit mit einem relativen Hinweis und eine Statuszeile, die sagt, ob das Token abgelaufen oder noch nicht gültig ist. Um die Signatur zu prüfen, trägst du das gemeinsame Secret oder den Public Key in Secret oder Public Key (optional) ein.
Hier ausprobieren: JWT-Decoder
Vollständige Tool-Seite öffnenDie drei Teile eines JWT
- Header: ein kleines JSON-Objekt wie {"alg":"HS256","typ":"JWT"}. alg nennt den Signaturalgorithmus; kid, falls vorhanden, sagt, welcher Schlüssel verwendet wurde, was hilft, wenn der Aussteller seine Schlüssel rotiert.
- Payload: die Claims, also Aussagen über den Nutzer und das Token, zum Beispiel Nutzer-ID, Aussteller, Zielgruppe, Rollen und Ablaufzeit. Jeder, der das Token hat, kann sie lesen.
- Signatur: berechnet über den kodierten Header und die Payload, mit einem Secret (HMAC) oder einem Private Key (RSA oder elliptische Kurven). Sie beweist, dass die ersten beiden Teile nicht verändert wurden und von jemandem stammen, der den Schlüssel besitzt.
- Ein Token mit fünf statt drei Teilen ist ein verschlüsseltes JWE. Seine Payload lässt sich ohne den Private Key nicht lesen, und das Tool sagt dir Bescheid, wenn du eines einfügst.
Häufige Claims und ihre Bedeutung
Der JWT-Standard (RFC 7519) registriert einige kurze Claim-Namen. Zeiten sind NumericDate-Werte: Sekunden seit dem 1. Januar 1970 UTC, keine Millisekunden. Das zu verwechseln ist ein klassischer Fehler, etwa wenn exp mit Date.now() aus JavaScript verglichen wird, das Millisekunden liefert.
| Claim | Name | Bedeutung |
|---|---|---|
| iss | Issuer (Aussteller) | Wer das Token erstellt hat, oft die URL des Identity Providers |
| sub | Subject (Subjekt) | Um wen es im Token geht, meist eine Nutzer-ID |
| aud | Audience (Zielgruppe) | Welche API oder App es annehmen soll |
| exp | Expiration time (Ablaufzeit) | Nach diesem Zeitpunkt muss das Token abgelehnt werden |
| nbf | Not before (gültig ab) | Vor diesem Zeitpunkt ist das Token noch nicht gültig |
| iat | Issued at (ausgestellt) | Wann das Token erstellt wurde |
| jti | JWT ID | Eindeutige ID, um Wiederverwendung zu verhindern oder ein Token zu sperren |
| auth_time | Authentication time (Anmeldezeit) | Wann sich der Nutzer tatsächlich angemeldet hat (OpenID Connect) |
Von Hand oder im Code dekodieren
Base64url unterscheidet sich vom normalen Base64: Es nutzt Minus und Unterstrich statt + und /, und das Auffüllzeichen = fällt weg. Die meisten Fehler beim Dekodieren entstehen, weil ein JWT-Teil direkt in einen normalen Base64-Decoder gesteckt wird. Ersetze Minus durch + und Unterstrich durch /, häng = an, bis die Länge ein Vielfaches von 4 ist, und dekodiere dann.
In Python erledigt base64.urlsafe_b64decode(teil + "==") das Alphabet, und das zusätzliche Auffüllen wird toleriert. In der Browserkonsole funktioniert atob, nachdem du die beiden Zeichen getauscht hast, liefert die Bytes aber als Latin 1; Umlaute wie in Müller oder andere Schriften in der Payload brauchen deshalb einen TextDecoder für korrektes UTF-8. Bibliotheken wie PyJWT, jsonwebtoken für Node.js oder System.IdentityModel.Tokens.Jwt für .NET dekodieren und prüfen in einem Aufruf; nutze im Produktivbetrieb ihre prüfende Funktion, keine Abkürzung, die nur dekodiert.
Für einen schnellen Blick ist ein Tool schneller und hinterlässt das Token nicht in deinem Shell-Verlauf.
Dekodieren ist nicht Prüfen
Die Payload zu lesen zeigt dir, was das Token behauptet; es beweist nicht, dass es stimmt. Jeder kann ein Token mit "role": "admin" erstellen und in Base64 kodieren. Erst eine gültige Signatur, geprüft mit dem richtigen Schlüssel, macht den Inhalt vertrauenswürdig. Server müssen immer prüfen, bevor sie irgendeinen Claim verwenden.
Im Tool werden Tokens mit HS256, HS384 und HS512 mit dem gemeinsamen Secret geprüft. RS-, PS- und ES-Tokens werden mit dem Public Key des Ausstellers im PEM-Format geprüft, also dem Block, der mit BEGIN PUBLIC KEY beginnt. Veröffentlicht dein Identity Provider die Schlüssel nur als JWKS-Liste, wandle den passenden Schlüssel (den, dessen kid zum Header passt) zuerst in PEM um. Das Ergebnis lautet Die Signatur ist gültig oder Die Signatur passt nicht zum Schlüssel. Fügst du einen Private Key ein, bittet dich das Tool stattdessen um den Public Key.
Achte auf diese Warnzeichen: alg ist none (das Token hat gar keine Signatur, und das Tool markiert es als unsigniert), ein unerwarteter Algorithmus (ein Server, der RS256 erwartet, darf nie ein HS256-Token annehmen, das ist ein bekannter Angriff) und Tokens, deren iss oder aud nicht zu deinem System passen.
Abgelaufene und ungültige Tokens: Fehlersuche
- Token abgelaufen: Prüf das Datum bei exp im Bereich Zeitangaben. Access Tokens leben oft absichtlich nur 5 bis 60 Minuten; die App sollte mit einem Refresh Token ein neues holen.
- Noch nicht gültig: nbf oder iat liegt in der Zukunft, meist weil die Uhr des Servers und die des Ausstellers voneinander abweichen. Viele Bibliotheken erlauben eine kleine Abweichung von einigen Sekunden bis Minuten; stell die Uhr per Zeitsynchronisierung richtig.
- Das sieht nicht wie ein JWT aus: Das Token wurde abgeschnitten, steht in Anführungszeichen oder enthält Leerzeichen vom Kopieren. Kopier es erneut aus dem Original-Header oder Cookie.
- Header oder Payload konnte nicht gelesen werden: Ein Teil des Tokens fehlt. Lange Tokens werden in Logs oft gekürzt.
- Signatur passt nicht: falsches Secret, der Public Key einer anderen Umgebung (Staging statt Produktion), ein rotierter Schlüssel oder ein verändertes Token.
Sicher mit Tokens umgehen
Ein gültiges Access Token funktioniert bis zum Ablauf wie ein Passwort. Füge echte Produktions-Tokens nicht in Websites ein, die sie an einen Server schicken, und poste sie nicht in Tickets oder Chats. Dieser Decoder läuft komplett in deinem Browser: Das Token wird weder gesendet noch protokolliert oder gespeichert.
Auf der Ausstellerseite gilt: Halte die Payload klein und frei von Geheimnissen. Da jeder sie lesen kann, gehören Passwörter, API-Schlüssel oder persönliche Daten, die der Client nicht sehen soll, nie in ein JWT. Speichere Nutzer-ID und Rollen und schlag alles andere auf dem Server nach.