Ich möchte die JWT-basierte Authentifizierung für unsere neue REST-API implementieren. Ist es jedoch möglich, den Ablauf automatisch zu verlängern, da er im Token festgelegt ist? Ich möchte nicht, dass sich Benutzer alle X Minuten anmelden müssen, wenn sie die Anwendung in diesem Zeitraum aktiv genutzt haben. Das wäre ein großer UX-Fehler.
Wenn Sie jedoch den Ablauf verlängern, wird ein neues Token erstellt (und das alte ist noch gültig, bis es abläuft). Und nach jeder Anfrage ein neues Token zu generieren, klingt für mich albern. Klingt nach einem Sicherheitsproblem, wenn mehr als ein Token gleichzeitig gültig ist. Natürlich könnte ich die alte gebrauchte mit einer schwarzen Liste ungültig machen, aber ich müsste die Token speichern. Und einer der Vorteile von JWT ist kein Speicher.
Ich habe herausgefunden, wie Auth0 es gelöst hat. Sie verwenden nicht nur ein JWT-Token, sondern auch ein Aktualisierungstoken: https://docs.auth0.com/refresh-token
Um dies zu implementieren (ohne Auth0), müsste ich Aktualisierungstoken speichern und deren Ablauf beibehalten. Was ist dann der wahre Vorteil? Warum nicht nur ein Token (nicht JWT) haben und den Ablauf auf dem Server behalten?
Gibt es noch andere Möglichkeiten? Ist die Verwendung von JWT für dieses Szenario nicht geeignet?
Antworten:
Ich arbeite bei Auth0 und war am Design der Funktion zum Aktualisieren von Token beteiligt.
Es hängt alles von der Art der Anwendung ab und hier ist unser empfohlener Ansatz.
Web Applikationen
Ein gutes Muster besteht darin, das Token vor Ablauf zu aktualisieren.
Stellen Sie den Token-Ablauf auf eine Woche ein und aktualisieren Sie den Token jedes Mal, wenn der Benutzer die Webanwendung öffnet, und alle eine Stunde. Wenn ein Benutzer die Anwendung länger als eine Woche nicht öffnet, muss er sich erneut anmelden. Dies ist eine akzeptable Webanwendung UX.
Um das Token zu aktualisieren, benötigt Ihre API einen neuen Endpunkt, der eine gültige, nicht abgelaufene JWT empfängt und dieselbe signierte JWT mit dem neuen Ablauffeld zurückgibt. Dann speichert die Webanwendung das Token irgendwo.
Mobile / native Anwendungen
Die meisten nativen Anwendungen melden sich einmal und nur einmal an.
Die Idee ist, dass das Aktualisierungstoken niemals abläuft und immer gegen ein gültiges JWT ausgetauscht werden kann.
Das Problem mit einem Token, das niemals abläuft, ist, dass es niemals niemals bedeutet. Was machst du, wenn du dein Handy verlierst? Es muss also für den Benutzer irgendwie 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 auf "Maryos iPad" widerrufen.
Ein anderer Ansatz besteht darin, das Aktualisierungstoken für bestimmte Ereignisse zu widerrufen. Ein interessantes Ereignis ist das Ändern 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.
quelle
In dem Fall, in dem Sie die Authentifizierung selbst durchführen (dh keinen Anbieter wie Auth0 verwenden), kann Folgendes funktionieren:
Das Flag 'reauth' im Datenbank-Backend wird gesetzt, wenn der Benutzer beispielsweise sein Kennwort zurückgesetzt hat. Das Flag wird entfernt, wenn sich der Benutzer das nächste Mal anmeldet.
Angenommen, Sie haben eine Richtlinie, nach der sich ein Benutzer mindestens alle 72 Stunden anmelden muss. In diesem Fall überprüft Ihre API-Token-Aktualisierungslogik auch das letzte Anmeldedatum des Benutzers aus der Benutzerdatenbank und verweigert / lässt die Token-Aktualisierung auf dieser Basis zu.
quelle
Ich habe herumgebastelt, als ich unsere Anwendungen mit RESTful apis im Backend auf HTML5 verschoben habe. Die Lösung, die ich gefunden habe, war:
Wie Sie sehen können, reduziert dies die häufigen Anforderungen für Aktualisierungstoken. Wenn der Benutzer den Browser / die App schließt, bevor der Aufruf zum Erneuern des Tokens ausgelöst wird, läuft das vorherige Token rechtzeitig ab und der Benutzer muss sich erneut anmelden.
Eine kompliziertere Strategie kann implementiert werden, um Benutzerinaktivität zu berücksichtigen (z. B. vernachlässigte geöffnete Browser-Registerkarte). In diesem Fall sollte der Aufruf des Erneuerungstokens die erwartete Ablaufzeit enthalten, die die definierte Sitzungszeit nicht überschreiten sollte. Die Anwendung muss die letzte Benutzerinteraktion entsprechend verfolgen.
Ich mag die Idee, einen langen Ablauf festzulegen, nicht, daher funktioniert dieser Ansatz möglicherweise nicht gut mit nativen Anwendungen, die eine weniger häufige Authentifizierung erfordern.
quelle
Eine alternative Lösung zum Ungültigmachen von JWTs ohne zusätzlichen sicheren Speicher im Backend besteht darin, eine neue
jwt_version
Ganzzahlspalte in der Benutzertabelle zu implementieren. Wenn der Benutzer vorhandene Token abmelden oder ablaufen lassen möchte, erhöht er einfach diejwt_version
Feld.Codieren Sie beim Generieren eines neuen JWT die
jwt_version
in die JWT-Nutzdaten und erhöhen Sie den Wert optional im Voraus, wenn die neue JWT alle anderen ersetzen soll.Bei der Validierung des JWT wird das
jwt_version
Feld neben dem verglichenuser_id
und die Autorisierung wird nur erteilt, wenn sie übereinstimmt.quelle
Gute Frage - und die Frage selbst enthält eine Fülle von Informationen.
Der Artikel Token aktualisieren: Wann sie verwendet werden und wie sie mit JWTs interagieren, bietet eine gute Idee für dieses Szenario. Einige Punkte sind: -
Schauen Sie sich auch auth0 / angle-jwt anglejs an
Für die Web-API. Lesen Sie OAuth-Aktualisierungstoken in AngularJS App mithilfe von ASP .NET Web API 2 und Owin aktivieren
quelle
Ich habe dies tatsächlich in PHP implementiert, indem ich den Guzzle-Client verwendet habe, um eine Client-Bibliothek für die API zu erstellen, aber das Konzept sollte für andere Plattformen funktionieren.
Grundsätzlich stelle ich zwei Token aus, einen kurzen (5 Minuten) und einen langen, der nach einer Woche abläuft. Die Clientbibliothek verwendet Middleware, um eine Aktualisierung des kurzen Tokens zu versuchen, wenn sie eine 401-Antwort auf eine Anforderung erhält. Anschließend wird die ursprüngliche Anforderung erneut versucht, und wenn eine Aktualisierung möglich war, wird die richtige Antwort transparent für den Benutzer angezeigt. Wenn dies fehlschlägt, wird der 401 nur an den Benutzer gesendet.
Wenn das kurze Token abgelaufen ist, aber immer noch authentisch und das lange Token gültig und authentisch ist, wird das kurze Token mithilfe eines speziellen Endpunkts auf dem Dienst aktualisiert, den das lange Token authentifiziert (dies ist das einzige, wofür es verwendet werden kann). Das kurze Token wird dann verwendet, um ein neues langes Token zu erhalten, wodurch es jedes Mal um eine weitere Woche verlängert wird, wenn das kurze Token aktualisiert wird.
Dieser Ansatz ermöglicht es uns auch, den Zugriff innerhalb von höchstens 5 Minuten zu widerrufen, was für unsere Verwendung akzeptabel ist, ohne dass eine schwarze Liste von Token gespeichert werden muss.
Späte Bearbeitung: Beim erneuten Lesen in diesem Monat, nachdem es in meinem Kopf frisch war, sollte ich darauf hinweisen, dass Sie den Zugriff beim Aktualisieren des kurzen Tokens widerrufen können, da dies die Möglichkeit für teurere Anrufe bietet (z. B. Aufruf der Datenbank, um festzustellen, ob der Benutzer dies tut wurde gesperrt), ohne bei jedem einzelnen Anruf bei Ihrem Dienst dafür zu bezahlen.
quelle
Im Folgenden finden Sie die Schritte zum Widerrufen Ihres JWT-Zugriffstokens:
1) Wenn Sie sich anmelden, senden Sie 2 Token (Zugriffstoken, Aktualisierungstoken) als Antwort an den Client.
2) Das Zugriffstoken hat weniger Ablaufzeit und das Aktualisieren hat eine lange Ablaufzeit.
3) Der Client (Front-End) speichert das Aktualisierungstoken in seinem lokalen Speicher und das Zugriffstoken in Cookies.
4) Der Client verwendet das Zugriffstoken zum Aufrufen von apis. Wenn es jedoch abläuft, wählen Sie das Aktualisierungstoken aus dem lokalen Speicher aus und rufen Sie die Authentifizierungsserver-API auf, um das neue Token zu erhalten.
5) Auf Ihrem Authentifizierungsserver wird eine API angezeigt, die ein Aktualisierungstoken akzeptiert, deren Gültigkeit überprüft und ein neues Zugriffstoken zurückgibt.
6) Sobald das Aktualisierungstoken abgelaufen ist, wird der Benutzer abgemeldet.
Bitte lassen Sie mich wissen, wenn Sie weitere Details benötigen, ich kann den Code (Java + Spring Boot) auch teilen.
quelle
jwt-autorefresh
Wenn Sie einen Knoten (React / Redux / Universal JS) verwenden, können Sie diesen installieren
npm i -S jwt-autorefresh
.Diese Bibliothek plant die Aktualisierung von JWT-Token mit einer vom Benutzer berechneten Anzahl von Sekunden vor Ablauf des Zugriffstokens (basierend auf dem im Token codierten Exp-Anspruch). Es verfügt über eine umfangreiche Testsuite und überprüft einige Bedingungen, um sicherzustellen, dass seltsame Aktivitäten von einer beschreibenden Meldung zu Fehlkonfigurationen in Ihrer Umgebung begleitet werden.
Vollständige Beispielimplementierung
Haftungsausschluss: Ich bin der Betreuer
quelle
jwt-autorefresh
dekodiert wird, ist das Extrahieren desexp
Anspruchs, damit bestimmt werden kann, wie weit die nächste Aktualisierung geplant ist.Ich habe dieses Problem durch Hinzufügen einer Variablen in den Token-Daten gelöst:
Ich habe die
expiresIn
Option auf die gewünschte Zeit eingestellt, bevor der Benutzer erneut angemeldet werden muss. Meins ist auf 30 Minuten eingestellt. Dies muss größer sein als der Wert vonsoftexp
.Wenn meine clientseitige App eine Anforderung an die Server-API sendet (wo ein Token erforderlich ist, z. B. eine Kundenlistenseite), prüft der Server anhand des ursprünglichen Ablaufwerts (
expiresIn
) , ob das übermittelte Token noch gültig ist oder nicht . Wenn es nicht gültig ist, antwortet der Server mit einem bestimmten Status für diesen Fehler, z.INVALID_TOKEN
.Wenn das Token basierend auf dem
expiredIn
Wert weiterhin gültig ist, den Wert jedoch bereits überschrittensoftexp
hat, antwortet der Server mit einem separaten Status für diesen Fehler, z.EXPIRED_TOKEN
::Wenn auf der Clientseite eine
EXPIRED_TOKEN
Antwort empfangen wurde , sollte das Token automatisch erneuert werden, indem eine Erneuerungsanforderung an den Server gesendet wird. Dies ist für den Benutzer transparent und wird automatisch für die Client-App erledigt.Die Erneuerungsmethode auf dem Server muss prüfen, ob das Token noch gültig ist:
Der Server lehnt die Erneuerung von Token ab, wenn die oben beschriebene Methode fehlgeschlagen ist.
quelle
Wie wäre es mit diesem Ansatz:
In diesem Fall benötigen wir keinen zusätzlichen Endpunkt zum Aktualisieren des Tokens. Würde mich über jeden Feedack freuen.
quelle
Heutzutage entscheiden sich viele Menschen für das Sitzungsmanagement mit JWTs, ohne zu wissen, was sie aus Gründen der wahrgenommenen Einfachheit aufgeben . Meine Antwort geht auf den 2. Teil der Fragen ein:
JWTs können das grundlegende Sitzungsmanagement mit einigen Einschränkungen unterstützen. Als selbstbeschreibende Token benötigen sie keinen Status auf der Serverseite. Das macht sie ansprechend. Wenn der Dienst beispielsweise keine Persistenzschicht hat, muss er nicht nur für die Sitzungsverwaltung eingefügt werden.
Staatenlosigkeit ist jedoch auch die Hauptursache für ihre Mängel. Da sie nur einmal mit festem Inhalt und Ablauf ausgegeben werden, können Sie mit einem typischen Sitzungsverwaltungs-Setup nicht die gewünschten Aktionen ausführen.
Sie können sie nämlich nicht bei Bedarf ungültig machen. Dies bedeutet, dass Sie keine sichere Abmeldung implementieren können, da bereits ausgegebene Token nicht ablaufen können. Sie können auch kein Leerlaufzeitlimit implementieren dem gleichen Grund . Eine Lösung besteht darin, eine schwarze Liste zu führen, die jedoch den Status einführt.
Ich habe einen Beitrag geschrieben, in dem diese Nachteile ausführlicher erläutert werden. Um es klar auszudrücken, können Sie diese umgehen, indem Sie mehr Komplexität hinzufügen (Schiebesitzungen, Aktualisierungstoken usw.).
Für andere Optionen empfehle ich dringend die Verwendung einer Cookie-basierten Sitzungsverwaltungslösung, wenn Ihre Kunden nur über einen Browser mit Ihrem Dienst interagieren. Ich habe auch eine Listenauthentifizierungsmethode zusammengestellt, die derzeit im Web weit verbreitet ist.
quelle