660 Stimmen

JWT (JSON Web Token) automatische Verlängerung des Ablaufdatums

Ich möchte JWT-basierte Authentifizierung in unsere neue REST-API implementieren. Da jedoch das Ablaufdatum im Token festgelegt ist, ist es möglich, es automatisch zu verlängern? Ich möchte nicht, dass Benutzer sich nach jedem X Minuten erneut anmelden müssen, wenn sie die Anwendung in diesem Zeitraum aktiv genutzt haben. Das wäre ein großer UX-Fehler.

Aber die Verlängerung des Ablaufdatums führt zu einem neuen Token (und der alte bleibt gültig, bis er abläuft). Und das Generieren eines neuen Tokens nach jeder Anfrage erscheint mir albern. Es klingt wie ein Sicherheitsproblem, wenn mehr als ein Token gleichzeitig gültig ist. Natürlich könnte ich das alte verwendete Token über eine Blacklist ungültig machen, aber ich müsste die Token speichern. Und einer der Vorteile von JWT ist, dass kein Speicherplatz benötigt wird.

Ich fand heraus, wie Auth0 es gelöst hat. Sie verwenden nicht nur das JWT-Token, sondern auch ein Refresh-Token: https://auth0.com/docs/tokens/refresh-tokens

Aber wiederum müsste ich zur Implementierung dieser Lösung (ohne Auth0) Refresh-Tokens speichern und deren Ablaufdatum verwalten. Was wäre dann der eigentliche Nutzen? Warum nicht nur ein Token (nicht JWT) haben und das Ablaufdatum auf dem Server behalten?

Gibt es andere Optionen? Ist die Verwendung von JWT für dieses Szenario nicht geeignet?

754voto

José F. Romaniello Punkte 13216

Ich arbeite bei Auth0 und war an der Gestaltung der Funktion zum Auffrischen des Tokens beteiligt.

Alles hängt vom Typ der Anwendung ab, hier ist unser empfohlener Ansatz.

Web-Anwendungen

Ein guter Ansatz ist es, das Token zu aktualisieren, bevor es abläuft.

Setzen Sie die Token-Ablaufzeit auf eine Woche und aktualisieren Sie das Token jedes Mal, wenn der Benutzer die Web-Anwendung öffnet, und alle Stunde. Wenn ein Benutzer die Anwendung länger als eine Woche nicht öffnet, muss er sich erneut anmelden, was eine akzeptable UX für Webanwendungen ist.

Um das Token zu aktualisieren, benötigt Ihre API einen neuen Endpunkt, der ein gültiges, nicht abgelaufenes JWT empfängt und dasselbe signierte JWT mit dem neuen Ablaufdatum zurückgibt. Anschließend speichert die Webanwendung das Token an einem Ort.

Mobile/Native Anwendungen

Die meisten nativen Anwendungen melden sich nur einmal an.

Die Idee ist, dass das Auffrischungstoken nie abläuft und immer gegen ein gültiges JWT eingetauscht werden kann.

Das Problem bei einem Token, der nie abläuft, ist, dass nie wirklich nie bedeutet. Was ist, wenn Sie Ihr Handy verlieren? Es muss also auf irgendeine Weise vom Benutzer identifizierbar sein, und die Anwendung muss eine Möglichkeit bieten, den Zugriff zu widerrufen. Wir haben uns entschieden, den Namen des Geräts zu verwenden, z.B. "Maryos iPad". Dann kann der Benutzer zur Anwendung gehen und den Zugriff für "Maryos iPad" widerrufen.

Ein anderer Ansatz ist es, das Auffrischungstoken bei bestimmten Ereignissen zu widerrufen. Ein interessantes Ereignis ist die Änderung des Passworts.

Wir glauben, dass JWT für diese Anwendungsfälle nicht nützlich ist, daher verwenden wir eine zufällig generierte Zeichenfolge und speichern sie auf unserer Seite.

84voto

IanB Punkte 2542

Im Falle, dass Sie die Authentifizierung selbst behandeln (also keinen Anbieter wie Auth0 verwenden), könnte Folgendes funktionieren:

  1. Erstellen Sie ein JWT-Token mit relativ kurzer Gültigkeitsdauer, z.B. 15 Minuten.
  2. Die Anwendung überprüft das Ablaufdatum des Tokens, bevor eine Transaktion, die einen Token erfordert, durchgeführt wird (der Token enthält das Ablaufdatum). Wenn der Token abgelaufen ist, fordert sie zunächst die API auf, den Token 'aufzufrischen' (dies geschieht für den Benutzer transparent).
  3. Die API erhält die Anfrage zur Aktualisierung des Tokens, prüft jedoch zunächst die Benutzerdatenbank, um zu sehen, ob eine 'Reauth'-Flagge gegen das Benutzerprofil gesetzt wurde (der Token kann die Benutzer-ID enthalten). Wenn die Flagge vorhanden ist, wird die Aktualisierung des Tokens verweigert, andernfalls wird ein neuer Token ausgestellt.
  4. Wiederholen.

Die 'Reauth'-Flagge in der Datenbank würde gesetzt werden, wenn beispielsweise der Benutzer sein Passwort zurückgesetzt hat. Die Flagge wird entfernt, wenn sich der Benutzer beim nächsten Mal anmeldet.

Zusätzlich nehmen wir an, Sie haben eine Richtlinie, nach der sich ein Benutzer mindestens alle 72 Stunden anmelden muss. In diesem Fall würde die Logik zur Aktualisierung des API-Tokens auch das Datum der letzten Anmeldung des Benutzers aus der Benutzerdatenbank überprüfen und die Aktualisierung des Tokens basierend darauf erlauben/verweigern.

30voto

Bhupinder Singh Punkte 3633

Im Folgenden finden Sie die Schritte zum Widerrufen Ihres JWT-Zugriffstokens:

1) Wenn Sie sich anmelden, senden Sie 2 Token (Zugriffstoken, Auffrischungstoken) als Antwort an den Client.
2) Das Zugriffstoken hat eine kürzere Ablaufzeit und das Auffrischungstoken eine längere Ablaufzeit.
3) Der Client (Front-End) speichert das Auffrischungstoken lokal und das Zugriffstoken in Cookies.
4) Der Client verwendet das Zugriffstoken zum Aufrufen von APIs. Wenn es abläuft, wird das Auffrischungstoken aus dem lokalen Speicher genommen und die Authentifizierungsserver-API aufgerufen, um ein neues Token zu erhalten.
5) Ihr Authentifizierungsserver hat eine API verfügbar, die das Auffrischungstoken akzeptiert, dessen Gültigkeit überprüft und ein neues Zugriffstoken zurückgibt.
6) Sobald das Auffrischungstoken abgelaufen ist, wird der Benutzer abgemeldet.

Bitte lassen Sie mich wissen, wenn Sie weitere Details benötigen. Ich kann den Code (Java + Spring Boot) ebenfalls teilen.

21voto

t7tran Punkte 1559

Ich habe herumgespielt, als ich unsere Anwendungen auf HTML5 mit RESTful APIs im Hintergrund umgestellt habe. Die Lösung, die ich gefunden habe, war:

  1. Dem Client wird bei erfolgreicher Anmeldung ein Token mit einer Sitzungsdauer von 30 Minuten (oder der üblichen serverseitigen Sitzungsdauer) zugewiesen.
  2. Es wird ein Client-seitiger Timer erstellt, um einen Dienst aufzurufen, um das Token vor seiner Ablaufzeit zu erneuern. Das neue Token ersetzt das bestehende bei zukünftigen Aufrufen.

Wie Sie sehen können, verringert dies die häufigen Anforderungen für das Erneuern des Tokens. Wenn der Benutzer den Browser/App schließt, bevor der Aufruf zum Erneuern des Tokens ausgelöst wird, wird das vorherige Token rechtzeitig ablaufen und der Benutzer muss sich erneut einloggen.

Es kann eine kompliziertere Strategie implementiert werden, um die Inaktivität des Benutzers (z.B. ein geöffnetes Browser-Tab vernachlässigt) zu berücksichtigen. In diesem Fall sollte der Aufruf zum Erneuern des Tokens die erwartete Ablaufzeit einschließen, die die definierte Sitzungsdauer nicht überschreiten sollte. Die Anwendung muss die letzte Benutzerinteraktion entsprechend verfolgen.

Ich mag die Idee einer langen Ablaufzeit nicht, daher funktioniert dieser Ansatz möglicherweise nicht gut bei nativen Anwendungen, die weniger häufige Authentifizierung erfordern.

20voto

Ollie Bennett Punkte 4274

Eine alternative Lösung zur Ungültigmachung von JWTs, ohne zusätzlichen sicheren Speicher auf dem Backend, besteht darin, eine neue jwt_version Integer-Spalte in der Benutzertabelle zu implementieren. Wenn der Benutzer sich abmelden oder vorhandene Tokens ablaufen lassen möchte, inkrementieren sie einfach das jwt_version Feld.

Beim Generieren eines neuen JWTs sollte die jwt_version in das JWT-Payload kodiert werden, wobei der Wert optional inkrementiert wird, wenn der neue JWT alle anderen ersetzen soll.

Beim Validieren des JWTs wird das jwt_version Feld zusammen mit der user_id verglichen, und die Autorisierung wird nur gewährt, wenn es übereinstimmt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X