Zurück

Funktionsweise von Token-basierter Authentifizierung am Beispiel des JSON Web Token (JWT)

Was ist ein JSON Web Token (JWT)?

Ein JSON Web Token (JWT) ist ein offener Standard (RFC 7519), der eine kompakte und selbstständige Methode für die sichere Übertragung von Informationen zwischen Parteien als JSON-Objekt definiert. Diese Informationen können überprüft und vertraut werden, da sie digital signiert sind. JWTs können mit einem Geheimnis (HMAC-Algorithmus) oder einem öffentlichen/privaten Schlüsselpaar (RSA oder ECDSA) signiert werden.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Struktur eines JWT

Ein JWT besteht aus drei Teilen, die durch Punkte (.) getrennt sind:

Header

Der Header besteht typischerweise aus zwei Teilen:

  • Dem Typ des Tokens (JWT)
  • Dem verwendeten Signaturalgorithmus (z.B. HMAC SHA256 oder RSA)
{
  "alg": "HS256",
  "typ": "JWT"
}

Dieser JSON wird Base64Url-codiert, um den ersten Teil des JWT zu bilden.

Payload

Der zweite Teil des Tokens ist die Payload, die die Claims (Ansprüche) enthält. Claims sind Aussagen über eine Entität (normalerweise den Benutzer) sowie zusätzliche Metadaten.

Es gibt drei Arten von Claims:

  • Registered Claims: Vordefinierte Claims wie iss (Issuer), exp (Expiration Time), sub (Subject), aud (Audience)
  • Public Claims: Können von JWT-Nutzern frei definiert werden
  • Private Claims: Benutzerdefinierte Claims, die zwischen Parteien vereinbart wurden
{
  "sub": "1234567890",
  "name": "Max Mustermann",
  "admin": true,
  "iat": 1516239022,
  "exp": 1516242622
}

Die Payload wird ebenfalls Base64Url-codiert, um den zweiten Teil des JWT zu bilden.

Signatur

Um die Signatur zu erstellen, müssen Sie den kodierten Header, die kodierte Payload, ein Geheimnis, den im Header angegebenen Algorithmus nehmen und diese signieren.

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

Die Signatur wird verwendet, um zu überprüfen, dass der Absender des JWT tatsächlich derjenige ist, der er vorgibt zu sein, und dass die Nachricht nicht verändert wurde.

Der Authentifizierungsprozess mit JWT

JWT Authentifizierungsfluss Diagramm
1
Anmeldung: Der Benutzer meldet sich mit seinen Anmeldedaten (z.B. Benutzername und Passwort) an.
2
Token-Generierung: Der Server überprüft die Anmeldedaten. Bei erfolgreicher Validierung erstellt er ein JWT mit einer Payload, die Benutzerinformationen und Berechtigungen enthält, und einer Signatur mit einem geheimen Schlüssel.
3
Token-Rückgabe: Der Server gibt das JWT an den Client zurück, der es lokal speichert (z.B. in localStorage, sessionStorage oder einem Cookie).
4
Zugriff auf geschützte Ressourcen: Bei nachfolgenden Anfragen sendet der Client das JWT im Authorization-Header (meist im Format "Bearer [token]").
5
Token-Validierung: Der Server überprüft die Signatur des JWT mit seinem geheimen Schlüssel und validiert die Claims (z.B. Ablaufzeit).
6
Antwort: Bei erfolgreicher Validierung gewährt der Server Zugriff auf die angeforderten Ressourcen.
Wichtig: Da JWTs selbstständig sind, muss der Server keine Sitzungsinformationen speichern. Alle notwendigen Informationen für die Authentifizierung und Autorisierung sind im Token selbst enthalten.

Implementierungsbeispiel

Server-seitige Token-Generierung (Node.js)

const jwt = require('jsonwebtoken');

// Benutzeranmeldung
app.post('/login', (req, res) => {
  // Benutzerauthentifizierung
  const { username, password } = req.body;

  // Validiere Benutzer (vereinfacht)
  if (username === 'admin' && password === 'password') {
    // Erstelle Token mit Benutzerinformationen
    const payload = {
      sub: 'user123',
      name: username,
      role: 'admin',
      iat: Math.floor(Date.now() / 1000),
      exp: Math.floor(Date.now() / 1000) + (60 * 60) // 1 Stunde gültig
    };

    const token = jwt.sign(payload, 'geheimer_schlüssel');

    // Sende Token zurück
    res.json({ token });
  } else {
    res.status(401).json({ message: 'Ungültige Anmeldedaten' });
  }
});

Server-seitige Token-Validierung (Node.js)

// Middleware zur Token-Validierung
const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

  if (!token) {
    return res.status(401).json({ message: 'Zugriff verweigert' });
  }

  jwt.verify(token, 'geheimer_schlüssel', (err, user) => {
    if (err) {
      return res.status(403).json({ message: 'Ungültiges oder abgelaufenes Token' });
    }

    req.user = user; // Füge entschlüsselte Benutzerdaten zum Request hinzu
    next();
  });
};

// Geschützte Route
app.get('/api/profile', authenticateToken, (req, res) => {
  res.json({ user: req.user });
});

Client-seitige Verwendung (JavaScript)

// Token nach der Anmeldung speichern
async function login() {
  const response = await fetch('/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'admin', password: 'password' })
  });

  const data = await response.json();
  localStorage.setItem('token', data.token);
}

// Token bei Anfragen verwenden
async function fetchProfile() {
  const token = localStorage.getItem('token');

  const response = await fetch('/api/profile', {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });

  const data = await response.json();
  console.log(data);
}

Vorteile der Token-basierten Authentifizierung mit JWT

Sicherheitshinweise

Zusammenfassung

Token-basierte Authentifizierung mit JWT bietet eine moderne, skalierbare und sichere Methode zur Benutzerauthentifizierung in Webanwendungen und APIs. Durch die selbstständige Natur von JWTs können Server zustandslos bleiben, während sie gleichzeitig die notwendigen Informationen zur Authentifizierung und Autorisierung von Benutzern bereitstellen.

Die dreischichtige Struktur aus Header, Payload und Signatur gewährleistet, dass die im Token enthaltenen Informationen vertrauenswürdig sind und nicht manipuliert wurden. Dies macht JWTs zu einer idealen Lösung für verteilte Systeme, Single Sign-On (SSO) und moderne Webarchitekturen.

Hinweis: Wählen Sie die Authentifizierungsmethode immer basierend auf den spezifischen Anforderungen Ihrer Anwendung. Für einige Anwendungsfälle können traditionelle Sitzungsbasierte Authentifizierungen oder OAuth 2.0 besser geeignet sein.