Wenn Sie sich bei einer modernen Single-Page-Anwendung (wie React oder Vue) oder einer mobilen App anmelden, benötigt der Server eine Möglichkeit, sich daran zu erinnern, wer Sie sind. Traditionell wurde dazu eine „Sitzungs-ID“ in einer riesigen Datenbank auf dem Server gespeichert und ein Cookie in Ihrem Browser abgelegt. Jedes Mal, wenn Sie auf eine Schaltfläche klickten, musste der Server diese ID in seiner Datenbank nachschlagen. Dies wird als zustandsbehaftete Authentifizierung bezeichnet.
Im Zeitalter von Microservices und Cloud-Skalierung wurden Datenbanken jedoch zu einem Flaschenhals. Um dieses Problem zu lösen, haben Entwickler die Zustandslose Authentifizierung über JSON Web Tokens (JWT) eingeführt. Mit JWT muss sich der Server nicht merken, wer Sie sind – Ihr Browser teilt dem Server genau mit, wer Sie sind, und verwendet Kryptografie, um dies zu beweisen.
Die Anatomie eines Zeugen Jehovas
Wenn Sie den Netzwerkverkehr überprüfen, nachdem Sie sich bei einer modernen App angemeldet haben, werden Sie wahrscheinlich den Header „Authorization: Bearer“ sehen, gefolgt von einer langen, zufällig aussehenden Zeichenfolge, die durch zwei Punkte getrennt ist. Das ist ein JWT.
Ein JWT besteht aus genau drei Teilen: Header.Payload.Signature.
1. Der Header
Der erste Teil ist ein Base64URL-codiertes JSON-Objekt, das lediglich das Token beschreibt. Es enthält normalerweise zwei Eigenschaften: den Typ des Tokens (JWT) und den verwendeten Signaturalgorithmus (z. B. HMAC SHA256 oder RSA).
2. Die Nutzlast (Ansprüche)
Der mittlere Teil ist ebenfalls ein Base64URL-codiertes JSON-Objekt. Hier befinden sich die eigentlichen Daten. Diese Daten werden „Ansprüche“ genannt. Es könnte beispielsweise Ihre Benutzer-ID, Ihre Rolle (z. B. „Admin“) und einen Ablaufzeitstempel enthalten. Da diese Nutzlast an jede Anfrage angehängt wird, erkennt der Server sofort, wer Sie sind, ohne eine Datenbank abzufragen.
KRITISCHE WARNUNG: Die Nutzlast ist lediglich codiert, nicht verschlüsselt. Jeder, der ein JWT abfängt, kann es leicht entschlüsseln und die Nutzlast lesen. Speichern Sie niemals Passwörter, Sozialversicherungsnummern oder sensible Daten in einer JWT-Nutzlast.
3. Die Signatur
Wenn jemand die Nutzlast lesen und bearbeiten kann, was hindert einen böswilligen Benutzer daran, seine Rolle von „Benutzer“ zu „Administrator“ zu ändern? Die Antwort ist die Signatur.
Um die Signatur zu erstellen, nimmt der Server den Header, die Nutzdaten und einen hochsicheren geheimen Schlüssel (der nur dem Server bekannt ist) und führt sie durch einen kryptografischen Algorithmus (wie SHA256). Der resultierende Hash wird zur Signatur.
Wenn der Server ein Token vom Client zurückerhält, berechnet er die Signatur mithilfe seines geheimen Schlüssels neu. Wenn der Benutzer die Nutzdaten manipuliert (sogar einen einzelnen Buchstaben geändert hat), stimmt die neu berechnete Signatur nicht mit der Signatur auf dem Token überein und der Server lehnt die Anfrage sofort als betrügerisch ab.
Überprüfen Sie Token sicher
Müssen Sie die Nutzlast eines JWT lesen, um Ihre Anwendung zu debuggen? Verwenden Sie unseren Offline-JWT-Decoder, um die Ansprüche sofort zu überprüfen, ohne Ihr sensibles Token an einen Remote-Server zu senden.
Öffnen Sie den JWT-DecoderWarum Microservices JWTs lieben
Stellen Sie sich ein Unternehmen wie Netflix vor. Sie verfügen über einen Authentifizierungsserver, einen Video-Streaming-Server und einen Abrechnungsserver. Würden sie herkömmliche Sitzungen verwenden, müsste jeder einzelne Server ständig mit einer zentralen Datenbank kommunizieren, um zu überprüfen, ob ein Benutzer angemeldet ist.
Bei JWTs signiert der Authentifizierungsserver das Token mit einem privaten Schlüssel. Der Benutzer übergibt dieses Token dann direkt an den Videoserver. Da der Videoserver über den öffentlichen Schlüssel verfügt, kann er die Signatur unabhängig überprüfen. Der Videoserver weiß genau, wer der Benutzer ist, ohne jemals mit dem Authentifizierungsserver oder einer Datenbank zu sprechen. Dies ermöglicht eine unbegrenzte Skalierung der Infrastruktur ohne Engpässe.
Die dunkle Seite: Token-Ungültigmachung
JWTs sind nicht perfekt. Ihre größte Stärke (Staatenlosigkeit) ist auch ihre größte Schwäche. Da der Server keine Aufzeichnungen über aktive Token führt, können Sie einen Benutzer nicht einfach abmelden oder ein bestimmtes Token ungültig machen, bevor es abläuft.
Wenn ein Hacker das JWT eines Benutzers stiehlt, hat der Hacker vollen Zugriff, bis der Ablaufzeitstempel des Tokens abgelaufen ist. Um dieses Risiko zu mindern, verwenden Sicherheitsingenieure ein Zwei-Token-System:
- Zugriffstokens: Kurzlebige JWTs (z. B. 15 Minuten), die für API-Anfragen verwendet werden.
- Aktualisierungstoken: Langlebige, zustandsbehaftete Token, die sicher gespeichert werden und ausschließlich zum Anfordern neuer Zugriffstoken verwendet werden. Wenn ein Konto kompromittiert wird, widerruft der Server das Aktualisierungstoken und das Zugriffstoken des Hackers wird natürlich innerhalb von 15 Minuten gelöscht.
Häufig gestellte Fragen (FAQ)
Wo soll ich ein JWT im Frontend speichern?
Das Speichern von JWTs in localStorage macht sie anfällig für Cross-Site Scripting (XSS)-Angriffe. Der sicherste Ort zum Speichern eines JWT in einem Webbrowser ist ein HttpOnly-Cookie, das verhindert, dass JavaScript darauf zugreift.
Was passiert, wenn der geheime Schlüssel meines Servers durchgesickert ist?
Katastrophe. Wenn ein Hacker Ihren geheimen HMAC-Schlüssel oder privaten RSA-Schlüssel erhält, kann er gültige JWTs mit jeder gewünschten Nutzlast generieren. Sie könnten Token erstellen, die sich selbst „Super Admin“-Rechte verleihen, und Ihr Server würde sie als gültig akzeptieren. Sie müssen Ihre Schlüssel sofort umdrehen.
Sind JWTs schneller als Sitzungscookies?
Nicht unbedingt. JWTs haben eine deutlich größere Dateigröße als eine 32-stellige Sitzungs-ID, was bedeutet, dass sie bei jeder Anfrage mehr Netzwerkbandbreite verbrauchen. Ihr Geschwindigkeitsvorteil ergibt sich vollständig aus der Umgehung von Datenbanksuchen im Backend.