JWT-Tokens verstehen: Ein vollständiger Leitfaden

· 12 Min. Lesezeit

Inhaltsverzeichnis

Was sind JSON Web Tokens (JWT)?

JSON Web Tokens (JWT) sind zum De-facto-Standard für die sichere Übertragung von Informationen zwischen Parteien in modernen Webanwendungen geworden. Definiert durch RFC 7519, bieten JWTs eine kompakte, URL-sichere Methode zur Darstellung von Claims, die zwischen zwei Parteien übertragen werden sollen.

Im Gegensatz zur traditionellen sitzungsbasierten Authentifizierung, bei der der Server den Zustand verwaltet, sind JWTs eigenständig. Das bedeutet, dass das Token selbst alle Informationen enthält, die zur Überprüfung der Identität und Berechtigungen eines Benutzers erforderlich sind. Diese zustandslose Natur macht JWTs besonders wertvoll in verteilten Systemen, Microservices-Architekturen und mobilen Anwendungen.

JWTs dienen zwei Hauptzwecken in modernen Anwendungen:

Die Schönheit von JWTs liegt in ihrer Einfachheit und Vielseitigkeit. Sie funktionieren nahtlos über verschiedene Programmiersprachen und Plattformen hinweg und sind daher ideal für heterogene Umgebungen, in denen Ihr Frontend in React, Ihr Backend in Node.js und Ihre mobile App in Swift oder Kotlin sein könnte.

Profi-Tipp: Obwohl JWTs unglaublich nützlich sind, sind sie keine Universallösung für alle Authentifizierungsszenarien. Zu verstehen, wann JWTs gegenüber traditionellen Sitzungen verwendet werden sollten, ist entscheidend für den Aufbau sicherer, skalierbarer Anwendungen.

Detaillierte JWT-Struktur und Anatomie

Ein JWT besteht aus drei verschiedenen Teilen, die durch Punkte (.) getrennt sind und eine Struktur bilden, die so aussieht: xxxxx.yyyyy.zzzzz. Jeder Abschnitt dient einem bestimmten Zweck und zusammen bilden sie ein manipulationssicheres Informationspaket.

Der Header

Der Header besteht typischerweise aus zwei Teilen: dem Typ des Tokens (JWT) und dem verwendeten Signaturalgorithmus, wie HMAC SHA256 oder RSA. Diese Information teilt der empfangenden Partei mit, wie die Signatur des Tokens validiert werden soll.

{
  "alg": "HS256",
  "typ": "JWT"
}

Der Header wird dann Base64Url-kodiert, um den ersten Teil des JWT zu bilden. Häufige Algorithmen, denen Sie begegnen werden, sind:

Die Payload

Die Payload enthält die Claims, die Aussagen über eine Entität (typischerweise den Benutzer) und zusätzliche Metadaten sind. Claims werden in drei Typen kategorisiert:

Registrierte Claims: Dies sind vordefinierte Claims, die nicht obligatorisch, aber zur Gewährleistung der Interoperabilität empfohlen sind. Sie umfassen:

Öffentliche Claims: Dies sind benutzerdefinierte Claims, die Sie für Ihre Anwendung definieren. Um Kollisionen zu vermeiden, sollten sie im IANA JSON Web Token Registry definiert oder kollisionsresistente Namen (wie Namespace-URIs) verwenden.

Private Claims: Benutzerdefinierte Claims, die erstellt wurden, um Informationen zwischen Parteien auszutauschen, die sich auf ihre Verwendung einigen. Dies sind weder registrierte noch öffentliche Claims.

{
  "sub": "1234567890",
  "name": "John Doe",
  "email": "[email protected]",
  "role": "admin",
  "iat": 1516239022,
  "exp": 1516242622
}

Die Payload wird dann Base64Url-kodiert, um den zweiten Teil des JWT zu bilden.

Schneller Tipp: Speichern Sie niemals sensible Informationen wie Passwörter oder Kreditkartennummern in JWT-Payloads. Obwohl JWTs signiert sind, sind sie standardmäßig nicht verschlüsselt, was bedeutet, dass jeder die Payload dekodieren und lesen kann.

Die Signatur

Die Signatur wird erstellt, indem der kodierte Header, die kodierte Payload, ein Geheimnis (für HMAC-Algorithmen) oder ein privater Schlüssel (für RSA/ECDSA) genommen und mit dem im Header angegebenen Algorithmus signiert werden.

Wenn beispielsweise HMAC SHA256 verwendet wird, würde die Signatur so erstellt:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

Die Signatur stellt sicher, dass das Token nicht verändert wurde. Wenn jemand auch nur ein einzelnes Zeichen im Header oder in der Payload ändert, schlägt die Signaturüberprüfung fehl.

Vollständiges JWT-Beispiel

Wenn Sie alle drei Teile zusammenfügen, erhalten Sie ein vollständiges JWT, das so aussieht:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Sie können jedes JWT mit unserem JWT-Decoder-Tool dekodieren und inspizieren, um seinen Header, seine Payload zu sehen und seine Signatur zu überprüfen.

JWTs in der Praxis erstellen und nutzen

Das Erstellen von JWTs ist mit den richtigen Bibliotheken unkompliziert. Lassen Sie uns untersuchen, wie JWTs über verschiedene Programmiersprachen und Szenarien hinweg generiert und verwendet werden.

JWTs in Node.js erstellen

Die jsonwebtoken-Bibliothek ist die beliebteste Wahl für Node.js-Anwendungen:

const jwt = require('jsonwebtoken');

// Token erstellen
const payload = {
  sub: user.id,
  email: user.email,
  role: user.role
};

const secret = process.env.JWT_SECRET;
const options = {
  expiresIn: '1h',
  issuer: 'myapp.com'
};

const token = jwt.sign(payload, secret, options);

// Token verifizieren
try {
  const decoded = jwt.verify(token, secret);
  console.log(decoded);
} catch (error) {
  console.error('Ungültiges Token:', error.message);
}

JWTs in Python erstellen

Python-Entwickler verwenden typischerweise die PyJWT-Bibliothek:

import jwt
import datetime

# Token erstellen
payload = {
    'sub': user.id,
    'email': user.email,
    'role': user.role,
    'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1),
    'iat': datetime.datetime.utcnow()
}

secret = os.environ.get('JWT_SECRET')
token = jwt.encode(payload, secret, algorithm='HS256')

# Token verifizieren
try:
    decoded = jwt.decode(token, secret, algorithms=['HS256'])
    print(decoded)
except jwt.ExpiredSignatureError:
    print('Token ist abgelaufen')
except jwt.InvalidTokenError:
    print('Ungültiges Token')

JWTs in Java erstellen

Für Java-Anwendungen wird die java-jwt-Bibliothek von Auth0 häufig verwendet:

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

// Token erstellen
Algorithm algorithm = Algorithm.HMAC256(secret);
String token = JWT.create()
    .withSubject(user.getId())
    .withClaim("email", user.getEmail())
    .withClaim("role", user.getRole())
    .withExpiresAt(new Date(System.currentTimeMillis() + 3600000))
    .withIssuer("myapp.com")
    .sign(algorithm);

// Token verifizieren
try {
    DecodedJWT jwt = JWT.require(algorithm)
        .withIssuer("myapp.com")
        .build()
        .verify(token);
} catch (Exception e) {
    System.out.println("Ungültiges Token: " + e.getMessage());
}

Best Practices für die Token-Generierung

Befolgen Sie beim Erstellen von JWTs diese Richtlinien, um Sicherheit und Zuverlässigkeit zu gewährleisten:

Profi-Tipp: Erwägen Sie die Implementierung eines Token-Refresh-Mechanismus mit Refresh-Tokens. Dies ermöglicht es Ihnen, Zugriffstokens aus Sicherheitsgründen kurzlebig zu halten und gleichzeitig eine gute Benutzererfahrung ohne häufige erneute Authentifizierung aufrechtzuerhalten.

JWT-Authentifizierungs-Workflow erklärt

Zu verstehen, wie JWTs durch Ihre Anwendung fließen, ist entscheidend für ihre korrekte Implementierung. Lassen Sie uns Schritt für Schritt durch einen typischen Authentifizierungs-Workflow gehen.

Initiale Authentifizierung

  1. Benutzer übermittelt Anmeldedaten: Der Benutzer sendet seinen Benutzernamen und sein Passwort an den Authentifizierungs-Endpunkt (typischerweise POST /api/auth/login).
  2. Server validiert Anmeldedaten: Der Server überprüft die Anmeldedaten gegen die Datenbank und verifiziert, dass der Passwort-Hash übereinstimmt.
  3. Server generiert JWT: Bei erfolgreicher Validierung erstellt der Server ein JWT, das die Identität des Benutzers und relevante Claims enthält.
  4. Server gibt Token zurück: Das JWT wird an den Client zurückgesendet, typischerweise im Response-Body. Einige Implementierungen setzen es auch als HTTP-only-Cookie.

Nachfolgende Anfragen

  1. Client fügt Token hinzu: Für jede nachfolgende Anfrage fügt der Client das JWT im Authorization-Header hinzu: Authorization: Bearer <token>
  2. Server validiert Token: Der Server extrahiert das Token, verifiziert seine Signatur und überprüft sein Ablaufdatum.
  3. Server verarbeitet Anfrage: Wenn das Token gültig ist, extrahiert der Server die Benutzerinformationen aus der Payload und verarbeitet die Anfrage entsprechend.
  4. Server gibt Antwort zurück: Die angeforderten Daten oder das Operationsergebnis werden an den Client zurückgegeben.

Token-Refresh-Flow

Wenn das Zugriffstoken abläuft, wird der Refresh-Flow aktiviert:

  1. Client erkennt Ablauf: Der Client erhält eine 401-Unauthorized-Antwort oder überprüft den exp-Claim des Tokens.
  2. Client sendet Refresh-Token: Der Client sendet das Refresh-Token an einen dedizierten Refresh-Endpunkt (POST /api/auth/refresh).
  3. Server validiert Refresh-Token: Der Server verifiziert das Refresh-Token und prüft, ob es widerrufen wurde.
  4. Server stellt neues Zugriffstoken aus: Ein neues Zugriffstoken wird generiert und an den Client zurückgegeben.
  5. Client wiederholt ursprüngliche Anfrage: Der Client verwendet das neue Zugriffstoken, um die fehlgeschlagene Anfrage zu wiederholen.

Logout-Flow

Das Abmelden mit JWTs erfordert besondere Überlegungen, da Tokens zustandslos sind:

  1. Client initiiert Logout: Der Benutzer klickt auf Abmelden, was eine Anfrage an POST /api/auth/logout auslöst.
  2. Server invalidiert Refresh-Token: Der Server fügt das Refresh-Token einer Widerrufsliste hinzu oder löscht es aus der Datenbank.
  3. Client verwirft Tokens: Der Client entfernt sowohl Zugriffs- als auch Refresh-Tokens aus dem Speicher.
  4. Client leitet um: Der Benutzer wird zur Anmeldeseite oder zum öffentlichen Bereich weitergeleitet.
Token-Typ Typische Lebensdauer Speicherort Zweck
Zugriffstoken 15 Min. - 1 Stunde Speicher oder sessionStorage API-Anfragen autorisieren
Refresh-Token 7 Tage - 30 Tage HTTP-only-Cookie oder sicherer Speicher Neue Zugriffstokens erhalten
ID-Token Gleich wie Zugriffstoken Speicher Benutzeridentitätsinformationen (OpenID Connect)

Schneller Tipp: Implementieren Sie automatisches Token-Refresh in Ihrer Client-Anwendung, um den Token-Ablauf nahtlos zu handhaben. Dies verhindert, dass Benutzer unerwartet abgemeldet

We use cookies for analytics. By continuing, you agree to our Privacy Policy.