JWT-Authentifizierung: Zustandslose Sicherheit
Sitzungen vs. JWTS. Die Debatte ist endlos. Wann man JSON-Web-Tokens verwendet, wie man sie sicher speichert (HttpOnly) und wie man mit der Rotation umgeht.
Die Sitzung vs. Token-Debatte
Sitzungsauthentifizierung (Der Klassiker):
- Benutzer meldet sich an.
- Der Server erstellt eine Sitzungs-ID („sess_123“). Speichert es im Speicher/Redis.
- Server sendet ID an Client-Cookie.
- Der Kunde sendet ein Cookie.
- Der Server sucht in Redis nach „sess_123“. Findet „Benutzer ist Bob“. Vorteile: Widerrufbar (Aus Redis löschen = Benutzer abgemeldet). Nachteile: Statefull. Sie brauchen Redis. Es ist schwieriger, über Regionen hinweg zu skalieren.
JWT Auth (The Modern):
- Benutzer meldet sich an.
- Der Server erstellt ein JSON-Web-Token. Enthält „{ id: 1, name: „Bob“ }“. Signiert es mit einem Geheimschlüssel.
- Der Server sendet JWT an den Client.
- Der Client sendet JWT.
- Der Server überprüft die Signatur. Findet „Benutzer ist Bob“. Vorteile: Staatenlos. Keine Datenbanksuche erforderlich. „Der Token ist die Sitzung“. Nachteile: Unwiderruflich. Bei Diebstahl bis zum Ablauf gültig.
Warum Maison Code dies bespricht
Bei Maison Code entwickeln wir Microservices und mobile Apps. Sitzungen sind für mobile Apps schrecklich (Cookies sind schwierig). Sitzungen sind für Microservices schrecklich (die gemeinsame Nutzung einer Redis-Instanz über 10 Dienste hinweg ist eine Kopplung). JWT ist der universelle Reisepass. Dienst A kann das vom Auth-Dienst ausgestellte Token überprüfen, indem er einfach den öffentlichen Schlüssel kennt. Wir implementieren strenge JWT-Abläufe, um unsere Headless-Architekturen zu ermöglichen.
Die Anatomie eines Zeugen Jehovas
Drei Teile, durch Punkte getrennt. „Header.Payload.Signature“.
- Header: Algorithmus (
HS256). - Nutzlast: Daten („sub: 123“, „exp: 17000000“).
- Signatur: „Hash(Header + Nutzlast + Geheimnis)“.
Kritisch: Die Nutzlast ist Base64-kodiert, NICHT verschlüsselt. Jeder kann es lesen („atob(token)“). Regel: Geben Sie niemals Geheimnisse in das JWT ein. Keine Passwörter. Keine Kreditkarten. Nur öffentliche Benutzer-IDs und Rollen.
Wo soll es aufbewahrt werden? (Der Heilige Krieg)
Option 1: LocalStorage
- Einfach (
localStorage.setItem('token', t)). - Anfällig für XSS. Wenn der Angreifer JS ausführt, liest er das Token.
Option 2: HttpOnly-Cookie
- Sicher. JS beschränkt den Zugriff.
- Anfällig für CSRF.
- Erfordert „SameSite=Strict“.
Urteil zum Maison Code: HttpOnly Cookie. CSRF ist einfacher zu entschärfen (SameSite) als XSS. Verwenden Sie für mobile Apps sicheren Speicher (Schlüsselbund).
Das Zugriffstoken-/Aktualisierungstokenmuster
Um das Problem der „Unwiderruflichen“ zu lösen.
- Zugriffstoken: Kurze Lebensdauer (5 Minuten). Wird zum Aufrufen der API verwendet.
- Refresh-Token: Lange Lebensdauer (7 Tage). Sicher gespeichert (HttpOnly/DB). Wird nur verwendet, um ein neues Zugriffstoken zu erhalten.
Fluss:
- Der Client führt einen API-Aufruf mit dem Zugriffstoken durch.
- Der Server meldet „401 abgelaufen“.
- Der Client ruft „/refresh-token“ mit Refresh Token auf.
- Der Server überprüft die Datenbank. „Ist dieses Aktualisierungs-Token blockiert? Nein.“
- Der Server stellt ein neues Zugriffstoken aus. Sicherheit: Wenn das Zugriffstoken gestohlen wird, funktioniert es 5 Minuten lang. Wenn Sie den Benutzer sperren, löschen Sie das Aktualisierungstoken aus der Datenbank. Sie werden in maximal 5 Minuten ausgesperrt.
Algorithmus: HS256 vs. RS256
- HS256 (Symmetrisch): Server signiert und verifiziert mit demselben Geheimnis. Schnell. Einfach für Monolithen.
- RS256 (asymmetrisch): Auth-Service signiert mit privatem Schlüssel. Andere Dienste überprüfen mit öffentlichem Schlüssel.
- Dies ist für Microservices von entscheidender Bedeutung. Der „Produktdienst“ kann den Benutzer verifizieren, ohne das Geheimnis des Auth-Dienstes zu kennen.
Die Sicht des Skeptikers
„Sitzungen sind einfacher.“ Gegenpunkt: Ja, für einen Monolithen mit einem Server. Versuchen Sie, Sitzungen durchzuführen, wenn Sie ein Next.js-Frontend auf Vercel Edge Network und ein Go-Backend auf AWS haben. Die Latenz von „Checking Redis“ beeinträchtigt die Edge-Leistung. JWT ermöglicht die Überprüfung der Authentifizierung am Edge (Signaturüberprüfung in 1 ms) ohne DB-Trip.
FAQ
F: Kann ich ein JWT manuell ungültig machen? A: Nein. Darum geht es. Sie können eine „Blacklist“ implementieren (ungültige JWT-IDs in Redis speichern), aber dann haben Sie Sessions neu erfunden. Verwenden Sie stattdessen kurze Ablaufzeiten.
F: Wie groß kann ein JWT sein? A: Halten Sie es klein. Es wird in jedem HTTP-Header gesendet. Wenn Sie 50 Berechtigungen eingeben, verlangsamen Sie jede Anfrage.
10. Token-Rotation (Die Aktualisierungskette)
Standard-Refresh-Tokens haben einen Fehler: Bei Diebstahl hat der Dieb 7 Tage lang Zugriff. Lösung: Token-Rotation aktualisieren.
- Der Client sendet Aktualisierungstoken A.
- Der Server gibt Zugriffstoken B UND Neues Aktualisierungstoken C zurück.
- Server löscht Aktualisierungstoken A. Wenn der Dieb erneut versucht, „Old Refresh Token A“ zu verwenden -> Sicherheitsalarm. Der Server erkennt die Wiederverwendung eines widerrufenen Tokens. Dadurch wird die gesamte „Token-Familie“ (A, C und alle Nachkommen) sofort ungültig. Der Dieb wird sofort ausgesperrt. Der echte Benutzer wird aufgefordert, sich erneut anzumelden.
11. JWKS (JSON Web Key Sets)
Wie rotieren Sie die Signaturschlüssel?
Sie können den öffentlichen Schlüssel nicht jede Woche neu in die Apps bündeln.
Lösung: JWKS-Endpunkt (/.well-known/jwks.json).
Der Auth-Server veröffentlicht seine öffentlichen Schlüssel unter einer URL.
Der Ressourcenserver ruft sie dynamisch ab (und speichert sie zwischen).
Wenn Sie eine Schlüsselkompromittierung vermuten, rotieren Sie den Schlüssel auf dem Authentifizierungsserver, aktualisieren das JWKS und jeder holt sich innerhalb von 5 Minuten den neuen Schlüssel.
12. OAuth 2.1 und die Zukunft
JWT ist nur das Token-Format. OAuth 2.0 ist der Ablauf. Die Branche stellt auf OAuth 2.1 um (Konsolidierung von Best Practices).
- Kein impliziter Fluss mehr (Zugriffstoken im URL-Hash).
- PKCE (Proof Key for Code Exchange) ist obligatorisch. Wir implementieren PKCE jetzt auch für serverseitige Web-Apps. Es verhindert „Authorization Code Injection“-Angriffe.
13. Maschine-zu-Maschine-Authentifizierung (Client-Anmeldeinformationen)
Was passiert, wenn „Cron Job A“ „API B“ aufrufen muss?
Es gibt keinen Benutzer. Kein Passwort.
Wir verwenden Client Credentials Flow.
POST /token { client_id, client_secret }.
Gibt ein JWT zurück.
Dies standardisiert Auth. Unabhängig davon, ob es sich um einen Benutzer („sub: user_1“) oder eine Maschine („sub: service_billing“) handelt, validiert die API lediglich die JWT-Signatur.
Einheitlichkeit ist Sicherheit.
14. Fazit
JWT ist die Währung des modernen Webs. Wie Geld muss es sorgfältig geprägt (Signieren), sicher aufbewahrt (Tresor) und auf Fälschungen überprüft (Verifizierung) werden. Rollen Sie nicht Ihre eigene Kryptowährung. Verwenden Sie Bibliotheken („jsonwebtoken“, „jose“).
Defekte Authentifizierung?
Wenn Benutzer zufällig abgemeldet werden oder Sie Token in LocalStorage speichern, kann Maison Code Ihren Authentifizierungsfluss sichern. Wir implementieren OAuth2-, OIDC- und JWT-Rotationsstrategien.
Kontaktieren Sie uns, um Ihre Logins zu sichern.
Authentifizierungsprobleme?
Wir sichern die zustandslose Authentifizierung mithilfe von JWTs (Access/Refresh-Muster) und HttpOnly-Cookies, um Identitäten über Mikrodienste hinweg zu schützen. Stellen Sie unsere Architekten ein.