Für ein neues node.js-Projekt, an dem ich arbeite, denke ich darüber nach, von einem Cookie-basierten Sitzungsansatz zu wechseln (damit meine ich das Speichern einer ID in einem Schlüsselwertspeicher, der Benutzersitzungen im Browser eines Benutzers enthält). zu einem tokenbasierten Sitzungsansatz (kein Schlüsselwertspeicher) unter Verwendung von JSON-Web-Tokens (jwt).
Das Projekt ist ein Spiel, das socket.io verwendet. Eine tokenbasierte Sitzung wäre in einem solchen Szenario nützlich, in dem mehrere Kommunikationskanäle in einer einzigen Sitzung vorhanden sind (web und socket.io).
Wie würde man mit dem jwt-Ansatz eine Token- / Sitzungsinvalidierung vom Server bereitstellen?
Ich wollte auch verstehen, auf welche häufigen (oder ungewöhnlichen) Fallstricke / Angriffe ich bei dieser Art von Paradigma achten sollte. Zum Beispiel, wenn dieses Paradigma für dieselben / unterschiedliche Arten von Angriffen anfällig ist wie der auf Session Store / Cookies basierende Ansatz.
Sagen wir also, ich habe folgendes (angepasst von diesem und jenem ):
Session Store Login:
app.get('/login', function(request, response) {
var user = {username: request.body.username, password: request.body.password };
// Validate somehow
validate(user, function(isValid, profile) {
// Create session token
var token= createSessionToken();
// Add to a key-value database
KeyValueStore.add({token: {userid: profile.id, expiresInMinutes: 60}});
// The client should save this session token in a cookie
response.json({sessionToken: token});
});
}
Token-basiertes Login:
var jwt = require('jsonwebtoken');
app.get('/login', function(request, response) {
var user = {username: request.body.username, password: request.body.password };
// Validate somehow
validate(user, function(isValid, profile) {
var token = jwt.sign(profile, 'My Super Secret', {expiresInMinutes: 60});
response.json({token: token});
});
}
- -
Eine Abmeldung (oder Ungültigmachung) für den Session Store-Ansatz würde eine Aktualisierung der KeyValueStore-Datenbank mit dem angegebenen Token erfordern.
Es scheint, als würde ein solcher Mechanismus im tokenbasierten Ansatz nicht existieren, da das Token selbst die Informationen enthalten würde, die normalerweise im Schlüsselwertspeicher vorhanden wären.
quelle
isRevoked
Option ansehen oder versuchen, dieselbe Funktionalität zu replizieren. github.com/auth0/express-jwt#revoked-tokensAntworten:
Auch ich habe diese Frage untersucht, und obwohl keine der folgenden Ideen vollständige Lösungen sind, können sie anderen helfen, Ideen auszuschließen oder weitere bereitzustellen.
1) Entfernen Sie einfach das Token vom Client
Dies hat natürlich nichts mit der serverseitigen Sicherheit zu tun, stoppt jedoch einen Angreifer, indem das Token aus der Existenz entfernt wird (dh, er müsste das Token vor dem Abmelden gestohlen haben).
2) Erstellen Sie eine Token-Blacklist
Sie können die ungültigen Token bis zu ihrem ursprünglichen Ablaufdatum speichern und mit eingehenden Anforderungen vergleichen. Dies scheint jedoch den Grund für die vollständige Token-basierte Verneinung zu negieren, da Sie die Datenbank für jede Anforderung berühren müssten. Die Speichergröße wäre jedoch wahrscheinlich geringer, da Sie nur Token speichern müssten, die zwischen Abmelde- und Ablaufzeit liegen (dies ist ein Bauchgefühl und hängt definitiv vom Kontext ab).
3) Halten Sie die Ablaufzeiten der Token einfach kurz und drehen Sie sie häufig
Wenn Sie die Ablaufzeiten des Tokens in ausreichend kurzen Intervallen einhalten und den laufenden Client bei Bedarf verfolgen und Aktualisierungen anfordern lassen, funktioniert Nummer 1 effektiv als vollständiges Abmeldesystem. Das Problem bei dieser Methode besteht darin, dass es unmöglich ist, den Benutzer zwischen dem Schließen des Client-Codes angemeldet zu halten (abhängig davon, wie lange Sie das Ablaufintervall einhalten).
Notfallpläne
Wenn jemals ein Notfall aufgetreten ist oder ein Benutzertoken kompromittiert wurde, können Sie dem Benutzer erlauben, eine zugrunde liegende Benutzersuch-ID mit ihren Anmeldeinformationen zu ändern. Dies würde alle zugeordneten Token ungültig machen, da der zugeordnete Benutzer nicht mehr gefunden werden kann.
Ich wollte auch darauf hinweisen, dass es eine gute Idee ist, das letzte Anmeldedatum in das Token aufzunehmen, damit Sie nach einiger Zeit eine erneute Anmeldung erzwingen können.
In Bezug auf Ähnlichkeiten / Unterschiede in Bezug auf Angriffe mit Token wird in diesem Beitrag die Frage behandelt: https://github.com/dentarg/blog/blob/master/_posts/2014-01-07-angularjs-authentication-with-cookies -vs-token.markdown
quelle
2)
oben. Obwohl es gut funktioniert, sehe ich persönlich keinen großen Unterschied zu herkömmlichen Session Stores. Ich denke, der Speicherbedarf wäre geringer, aber Sie benötigen immer noch eine Datenbank. Der größte Reiz von JWT war für mich, überhaupt keine Datenbank für Sitzungen zu verwenden.Die oben genannten Ideen sind gut, aber eine sehr einfache und einfache Möglichkeit, alle vorhandenen JWTs ungültig zu machen, besteht darin, einfach das Geheimnis zu ändern.
Wenn Ihr Server das JWT erstellt, es mit einem Geheimnis (JWS) signiert und dann an den Client sendet, werden durch einfaches Ändern des Geheimnisses alle vorhandenen Token ungültig und alle Benutzer müssen ein neues Token zur Authentifizierung erhalten, da ihr altes Token plötzlich ungültig wird zum Server.
Es sind keine Änderungen am tatsächlichen Token-Inhalt (oder an der Lookup-ID) erforderlich.
Dies funktioniert natürlich nur in einem Notfall, in dem alle vorhandenen Token ablaufen sollen. Für das Ablaufen eines Tokens ist eine der oben genannten Lösungen erforderlich (z. B. kurze Ablaufzeit des Tokens oder Ungültigmachen eines im Token gespeicherten Schlüssels).
quelle
Dies ist in erster Linie ein langer Kommentar, der die Antwort von @mattway unterstützt und darauf aufbaut
Gegeben:
Einige der anderen auf dieser Seite vorgeschlagenen Lösungen empfehlen, bei jeder Anforderung den Datenspeicher aufzurufen. Wenn Sie den Hauptdatenspeicher aufrufen, um jede Authentifizierungsanforderung zu validieren, sehe ich weniger Gründe, JWT anstelle anderer etablierter Token-Authentifizierungsmechanismen zu verwenden. Sie haben JWT im Wesentlichen statusbehaftet und nicht zustandslos gemacht, wenn Sie jedes Mal zum Datenspeicher gehen.
(Wenn Ihre Site eine große Anzahl nicht autorisierter Anfragen erhält, würde JWT diese ablehnen, ohne den Datenspeicher zu erreichen, was hilfreich ist. Es gibt wahrscheinlich andere Anwendungsfälle wie diesen.)
Gegeben:
Eine wirklich zustandslose JWT-Authentifizierung kann für eine typische reale Web-App nicht erreicht werden, da zustandslose JWT keine Möglichkeit bietet, sofortige und sichere Unterstützung für die folgenden wichtigen Anwendungsfälle bereitzustellen :
Das Benutzerkonto wird gelöscht / gesperrt / gesperrt.
Das Passwort des Benutzers wird geändert.
Die Rollen oder Berechtigungen des Benutzers werden geändert.
Der Benutzer wird vom Administrator abgemeldet.
Alle anderen anwendungskritischen Daten im JWT-Token werden vom Site-Administrator geändert.
In diesen Fällen können Sie nicht auf den Ablauf des Tokens warten. Die Token-Ungültigmachung muss sofort erfolgen. Sie können dem Client auch nicht vertrauen, dass er keine Kopie des alten Tokens aufbewahrt und verwendet, sei es mit böswilliger Absicht oder nicht.
Deshalb: Ich denke, die Antwort von @ matt-way, # 2 TokenBlackList, wäre die effizienteste Möglichkeit, der JWT-basierten Authentifizierung den erforderlichen Status hinzuzufügen.
Sie haben eine schwarze Liste, die diese Token enthält, bis ihr Ablaufdatum erreicht ist. Die Liste der Token ist im Vergleich zur Gesamtzahl der Benutzer recht klein, da nur Token auf der schwarzen Liste bis zu ihrem Ablauf aufbewahrt werden müssen. Ich würde implementieren, indem ungültige Token in Redis, Memcached oder einem anderen speicherinternen Datenspeicher abgelegt werden, der das Festlegen einer Ablaufzeit für einen Schlüssel unterstützt.
Sie müssen weiterhin für jede Authentifizierungsanforderung, die die anfängliche JWT-Authentifizierung besteht, einen Anruf bei Ihrer In-Memory-Datenbank tätigen, müssen jedoch nicht die Schlüssel für Ihre gesamte Benutzergruppe darin speichern. (Was für eine bestimmte Site eine große Sache sein kann oder nicht.)
quelle
If the JWT contains the necessary data, the need to query the database for certain operations may be reduced, though this may not always be the case.
Ich würde die jwt-Versionsnummer auf dem Benutzermodell aufzeichnen. Neue JWT-Token würden ihre Version darauf einstellen.
Wenn Sie das JWT validieren, überprüfen Sie einfach, ob es eine Versionsnummer hat, die der aktuellen JWT-Version des Benutzers entspricht.
Jedes Mal, wenn Sie alte JWTS ungültig machen möchten, geben Sie einfach die JWT-Versionsnummer des Benutzers an.
quelle
Ich habe dies noch nicht versucht und es werden viele Informationen verwendet, die auf einigen der anderen Antworten basieren. Die Komplexität besteht darin, einen serverseitigen Datenspeicheraufruf pro Anforderung von Benutzerinformationen zu vermeiden. Die meisten anderen Lösungen erfordern eine Datenbank-Suche pro Anforderung an einen Benutzersitzungsspeicher. Das ist in bestimmten Szenarien in Ordnung, wurde jedoch erstellt, um solche Aufrufe zu vermeiden und den erforderlichen serverseitigen Status sehr klein zu halten. Am Ende wird eine serverseitige Sitzung neu erstellt, die jedoch klein ist, um alle Funktionen zur erzwungenen Ungültigmachung bereitzustellen. Aber wenn Sie es hier tun möchten, ist das Wesentliche:
Tore:
Die Lösung:
Dies erfordert, dass Sie eine Blacklist (Status) auf dem Server verwalten, vorausgesetzt, die Benutzertabelle enthält gesperrte Benutzerinformationen. Die Blacklist für ungültige Sitzungen - ist eine Liste der Benutzer-IDs. Diese schwarze Liste wird nur während einer Aktualisierungstokenanforderung überprüft. Einträge sind erforderlich, um darauf zu leben, solange das Aktualisierungstoken TTL. Nach Ablauf des Aktualisierungstokens muss sich der Benutzer erneut anmelden.
Nachteile:
Vorteile:
Mit dieser Lösung wird kein In-Memory-Datenspeicher wie reddis benötigt, zumindest nicht für Benutzerinformationen, da der Server nur etwa alle 15 Minuten einen Datenbankaufruf tätigt. Wenn Sie reddis verwenden, ist das Speichern einer gültigen / ungültigen Sitzungsliste eine sehr schnelle und einfachere Lösung. Kein Aktualisierungstoken erforderlich. Jedes Authentifizierungstoken hätte eine Sitzungs-ID und eine Geräte-ID. Sie könnten bei der Erstellung in einer reddis-Tabelle gespeichert und gegebenenfalls ungültig gemacht werden. Dann würden sie bei jeder Anfrage überprüft und bei Ungültigkeit abgelehnt.
quelle
Ein Ansatz, über den ich nachgedacht habe, besteht darin, immer einen
iat
(ausgegebenen) Wert in der JWT zu haben. Wenn sich ein Benutzer abmeldet, speichern Sie diesen Zeitstempel im Benutzerdatensatz. Vergleichen Sie bei der Validierung des JWT einfachiat
den zuletzt abgemeldeten Zeitstempel. Wenn dasiat
älter ist, ist es nicht gültig. Ja, Sie müssen zur Datenbank gehen, aber ich werde trotzdem immer den Benutzerdatensatz abrufen, wenn die JWT ansonsten gültig ist.Der größte Nachteil, den ich sehe, ist, dass sie von allen Sitzungen abgemeldet werden, wenn sie sich in mehreren Browsern befinden oder auch einen mobilen Client haben.
Dies könnte auch ein guter Mechanismus sein, um alle JWTs in einem System ungültig zu machen. Ein Teil der Prüfung könnte gegen einen globalen Zeitstempel der letzten gültigen
iat
Zeit erfolgen.quelle
token_valid_after
oder so. Genial!Ich bin hier etwas spät dran, aber ich denke, ich habe eine anständige Lösung.
Ich habe eine Spalte "last_password_change" in meiner Datenbank, in der Datum und Uhrzeit der letzten Änderung des Kennworts gespeichert sind. Ich speichere auch das Datum / die Uhrzeit der Ausgabe im JWT. Bei der Validierung eines Tokens überprüfe ich, ob das Kennwort nach der Ausgabe des Tokens geändert wurde und ob das Token abgelehnt wurde, obwohl es noch nicht abgelaufen ist.
quelle
if (jwt.issue_date < user.last_pw_change) { /* not valid, redirect to login */}
Sie können ein "last_key_used" -Feld in Ihrer Datenbank im Dokument / Datensatz Ihres Benutzers haben.
Wenn sich der Benutzer mit Benutzer anmeldet und übergibt, generieren Sie eine neue zufällige Zeichenfolge, speichern Sie sie im Feld last_key_used und fügen Sie sie beim Signieren des Tokens zur Nutzlast hinzu.
Wenn sich der Benutzer mit dem Token anmeldet, überprüfen Sie, ob der in der Datenbank verwendete last_key_key mit dem im Token übereinstimmt.
Wenn der Benutzer beispielsweise eine Abmeldung vornimmt oder wenn Sie das Token ungültig machen möchten, ändern Sie einfach das Feld "last_key_used" in einen anderen zufälligen Wert. Alle nachfolgenden Überprüfungen schlagen fehl, sodass der Benutzer sich mit dem Benutzer anmelden und erneut übergeben muss.
quelle
Führen Sie eine solche In-Memory-Liste
Wenn Ihre Token in einer Woche ablaufen, bereinigen oder ignorieren Sie die älteren Datensätze. Bewahren Sie außerdem nur die neuesten Aufzeichnungen jedes Benutzers auf. Die Größe der Liste hängt davon ab, wie lange Sie Ihre Token aufbewahren und wie oft Benutzer ihre Token widerrufen. Verwenden Sie db nur, wenn sich die Tabelle ändert. Laden Sie die Tabelle in den Speicher, wenn Ihre Anwendung gestartet wird.
quelle
------------------------ Etwas spät für diese Antwort, aber es kann sein, dass es jemandem hilft ------------- -----------
Auf der Clientseite ist es am einfachsten, das Token aus dem Speicher des Browsers zu entfernen.
Was ist, wenn Sie das Token auf dem Knotenserver zerstören möchten?
Das Problem mit dem JWT-Paket ist, dass es keine Methode oder Möglichkeit zum Zerstören des Tokens bietet. Sie können in Bezug auf JWT verschiedene Methoden verwenden, die oben erwähnt wurden. Aber hier gehe ich mit den JWT-Redis.
Um das Token auf der Serverseite zu zerstören, können Sie anstelle von JWT das Paket jwt-redis verwenden
Diese Bibliothek (jwt-redis) wiederholt die gesamte Funktionalität der Bibliothek jsonwebtoken mit einer wichtigen Ergänzung vollständig. Mit Jwt-redis können Sie das Token-Label in redis speichern, um die Gültigkeit zu überprüfen. Das Fehlen eines Token-Labels in redis macht das Token ungültig. Um das Token in jwt-redis zu zerstören, gibt es eine Zerstörungsmethode
es funktioniert so:
1) Installieren Sie jwt-redis von npm
2) Erstellen -
3) Zur Überprüfung -
4) Zu zerstören -
Hinweis : Sie können expiresIn während der Anmeldung des Tokens auf dieselbe Weise wie in JWT bereitstellen.
Vielleicht hilft das jemandem
quelle
Warum nicht einfach den jti-Claim (nonce) verwenden und diesen in einer Liste als Benutzerdatensatzfeld speichern (db-abhängig, aber zumindest eine durch Kommas getrennte Liste ist in Ordnung)? Es ist keine separate Suche erforderlich, da andere darauf hingewiesen haben, dass Sie den Benutzerdatensatz vermutlich trotzdem erhalten möchten. Auf diese Weise können Sie mehrere gültige Token für verschiedene Clientinstanzen haben ("Überall abmelden" kann die Liste auf leer zurücksetzen).
quelle
Überprüfen Sie für die Token-Validierung zuerst die Ablaufzeit des Tokens und dann die Blacklist, wenn das Token nicht abgelaufen ist.
Für lange Sitzungsanforderungen sollte es einen Mechanismus zum Verlängern der Token-Ablaufzeit geben.
quelle
Spät zur Party werden nach einigen Recherchen MEINE zwei Cent unten angegeben. Stellen Sie beim Abmelden sicher, dass folgende Dinge geschehen ...
Löschen Sie den Client-Speicher / die Client-Sitzung
Aktualisieren Sie die Benutzertabelle beim letzten Anmeldedatum und beim letzten Abmeldedatum, wenn die Anmeldung bzw. Abmeldung erfolgt. Die Uhrzeit des Anmeldedatums sollte daher immer größer als die Abmeldedate sein (oder das Abmeldedatum auf Null belassen, wenn der aktuelle Status "Anmelden" und noch nicht abgemeldet ist).
Dies ist weitaus einfacher, als eine zusätzliche schwarze Liste zu führen und regelmäßig zu löschen. Für die Unterstützung mehrerer Geräte ist eine zusätzliche Tabelle erforderlich, um angemeldet zu bleiben. Abmeldedaten mit einigen zusätzlichen Details wie Betriebssystem- oder Clientdetails.
quelle
Einzigartig pro Benutzerzeichenfolge und globaler String, der zusammen gehasht wurde
Um als geheimer JWT-Teil zu dienen, können sowohl einzelne als auch globale Token ungültig gemacht werden. Maximale Flexibilität auf Kosten einer Datenbank-Suche / -Lesung während der Anforderungsauthentifizierung. Auch einfach zwischenzuspeichern, da sie sich selten ändern.Hier ist ein Beispiel:
Beispiel: Verwendung siehe https://jwt.io (nicht sicher, ob sie mit dynamischen 256-Bit-Geheimnissen umgehen)
quelle
Ich habe es folgendermaßen gemacht:
unique hash
und speichern Sie es in redis und Ihrem JWT . Dies kann als Sitzung bezeichnet werdenWenn sich ein Benutzer anmeldet, wird ein eindeutiger Hash erstellt, in redis gespeichert und in Ihr JWT eingefügt .
Wenn ein Benutzer versucht, einen geschützten Endpunkt zu besuchen, greifen Sie auf den eindeutigen Sitzungs-Hash von Ihrem JWT zu , fragen Redis ab und prüfen , ob er übereinstimmt!
Wir können daraus erweitern und unser JWT noch sicherer machen. So geht's:
Bei jeder X- Anforderung, die eine bestimmte JWT gestellt hat, generieren wir eine neue eindeutige Sitzung, speichern sie in unserer JWT und setzen die vorherige auf die schwarze Liste.
Dies bedeutet, dass sich die JWT ständig ändert und verhindert, dass abgestandene JWT gehackt, gestohlen oder etwas anderes wird.
quelle
aud
undjti
behauptet in JWT, Sie sind auf dem richtigen Weg.Wenn Sie Benutzertoken widerrufen möchten, können Sie alle ausgegebenen Token in Ihrer Datenbank verfolgen und prüfen, ob sie in einer sitzungsähnlichen Tabelle gültig (vorhanden) sind. Der Nachteil ist, dass Sie die DB bei jeder Anfrage treffen.
Ich habe es nicht ausprobiert, aber ich schlage die folgende Methode vor, um die Token-Sperrung zu ermöglichen und gleichzeitig die DB-Treffer auf ein Minimum zu beschränken:
Um die Datenbankprüfrate zu senken, teilen Sie alle ausgegebenen JWT-Token gemäß einer deterministischen Zuordnung (z. B. 10 Gruppen nach der ersten Ziffer der Benutzer-ID) in X-Gruppen auf.
Jedes JWT-Token enthält die Gruppen-ID und einen Zeitstempel, der bei der Token-Erstellung erstellt wurde. z.B,
{ "group_id": 1, "timestamp": 1551861473716 }
Der Server speichert alle Gruppen-IDs im Speicher und jede Gruppe verfügt über einen Zeitstempel, der angibt, wann das letzte Abmeldeereignis eines Benutzers war, der zu dieser Gruppe gehört. z.B,
{ "group1": 1551861473714, "group2": 1551861487293, ... }
Anforderungen mit einem JWT-Token mit einem älteren Gruppenzeitstempel werden auf Gültigkeit überprüft (DB-Treffer). Wenn sie gültig sind, wird ein neues JWT-Token mit einem neuen Zeitstempel für die zukünftige Verwendung durch den Client ausgegeben. Wenn der Gruppenzeitstempel des Tokens neuer ist, vertrauen wir dem JWT (kein DB-Treffer).
Damit -
quelle
Wenn die Option "Von allen Geräten abmelden" akzeptabel ist (in den meisten Fällen):
In den meisten Fällen ist ohnehin eine Datenbankauslösung erforderlich, um den Benutzerdatensatz abzurufen, sodass der Validierungsprozess nicht viel Aufwand verursacht. Im Gegensatz zur Verwaltung einer Blacklist, bei der die DB-Last aufgrund der Notwendigkeit, einen Join oder einen separaten Aufruf zu verwenden, erheblich ist, bereinigen Sie alte Datensätze usw.
quelle
Ich werde antworten, wenn wir bei Verwendung von JWT eine Abmeldung von allen Gerätefunktionen bereitstellen müssen. Bei diesem Ansatz werden für jede Anforderung Datenbanksuchen verwendet. Weil wir einen Persistenzsicherheitsstatus benötigen, selbst wenn es zu einem Serverabsturz kommt. In der Benutzertabelle haben wir zwei Spalten
Immer wenn der Benutzer eine Abmeldeanforderung erhält, aktualisieren wir LastValidTime auf die aktuelle Zeit und Logged In auf false. Wenn eine Anmeldeanforderung vorliegt, ändern wir LastValidTime nicht, aber Logged-In wird auf true gesetzt.
Wenn wir das JWT erstellen, haben wir die JWT-Erstellungszeit in der Nutzlast. Wenn wir einen Service autorisieren, überprüfen wir 3 Bedingungen
Sehen wir uns ein praktisches Szenario an.
Benutzer X hat zwei Geräte A, B. Er hat sich um 19 Uhr mit Gerät A und Gerät B bei unserem Server angemeldet (sagen wir, die JWT-Ablaufzeit beträgt 12 Stunden). A und B haben beide JWT mit createdTime: 7pm
Um 21 Uhr verlor er sein Gerät B. Er meldet sich sofort von Gerät A ab. Das bedeutet, dass unser Benutzereintrag in Datenbank X jetzt LastValidTime als "ThatDate: 9: 00: xx: xxx" und als "false" angemeldet hat.
Um 9:30 Uhr versucht Mr.Thief, sich mit Gerät B anzumelden. Wir überprüfen die Datenbank, auch wenn die Anmeldung falsch ist, sodass wir dies nicht zulassen.
Um 22 Uhr meldet sich Mr.X von seinem Gerät A aus an. Jetzt hat Gerät A JWT mit der erstellten Zeit: 22 Uhr. Jetzt ist die angemeldete Datenbank auf "true" gesetzt.
Um 22:30 Uhr versucht Mr.Thief, sich anzumelden. Obwohl das Angemeldete wahr ist. Die LastValidTime ist 21 Uhr in der Datenbank, aber B's JWT hat die Zeit als 19 Uhr erstellt. Er darf also nicht auf den Dienst zugreifen. Wenn er also Gerät B ohne Kennwort verwendet, kann er das bereits erstellte JWT nicht verwenden, nachdem sich ein Gerät abgemeldet hat.
quelle
IAM-Lösungen wie Keycloak (an denen ich gearbeitet habe) bieten Token Revocation-Endpunkte wie
Token-Sperrendpunkt
/realms/{realm-name}/protocol/openid-connect/revoke
Wenn Sie einfach einen Benutzeragenten (oder Benutzer) abmelden möchten, können Sie auch einen Endpunkt aufrufen (dies würde die Token einfach ungültig machen). Auch im Fall von Keycloak muss die vertrauende Partei nur den Endpunkt anrufen
/realms/{realm-name}/protocol/openid-connect/logout
Link für den Fall, dass Sie mehr erfahren möchten
quelle
Dies scheint wirklich schwer zu lösen zu sein, ohne dass bei jeder Token-Überprüfung eine DB-Suche durchgeführt wird. Die Alternative, die ich mir vorstellen kann, besteht darin, eine schwarze Liste ungültiger Token auf der Serverseite zu führen. Dies sollte in einer Datenbank aktualisiert werden, wenn eine Änderung die Änderungen über Neustarts hinweg beibehält, indem der Server die Datenbank beim Neustart überprüft, um die aktuelle Blacklist zu laden.
Wenn Sie es jedoch im Serverspeicher behalten (eine Art globale Variable), kann es nicht auf mehrere Server skaliert werden, wenn Sie mehr als einen verwenden. In diesem Fall können Sie es also in einem gemeinsam genutzten Redis-Cache aufbewahren Einrichtung, um die Daten irgendwo zu speichern (Datenbank? Dateisystem?), falls sie neu gestartet werden müssen, und jedes Mal, wenn ein neuer Server hochgefahren wird, muss er den Redis-Cache abonnieren.
Alternativ zu einer schwarzen Liste können Sie mit derselben Lösung einen in Redis pro Sitzung gespeicherten Hash verwenden, wie in dieser anderen Antwort angegeben (nicht sicher, ob dies effizienter wäre, wenn sich viele Benutzer anmelden).
Klingt es schrecklich kompliziert? es tut mir an!
Haftungsausschluss: Ich habe Redis nicht verwendet.
quelle
Wenn Sie Axios oder eine ähnliche versprechungsbasierte http-Anforderungsbibliothek verwenden, können Sie das Token im Front-End innerhalb des
.then()
Teils einfach zerstören . Es wird im Antwortteil .then () gestartet, nachdem der Benutzer diese Funktion ausgeführt hat (der Ergebniscode vom Serverendpunkt muss in Ordnung sein, 200). Nachdem der Benutzer bei der Suche nach Daten auf diese Route geklickt hat und das Datenbankfelduser_enabled
falsch ist, wird das Token zerstört, und der Benutzer wird sofort abgemeldet und kann nicht mehr auf geschützte Routen / Seiten zugreifen. Wir müssen nicht warten, bis das Token abläuft, während der Benutzer dauerhaft angemeldet ist.quelle
Ich speichere nur das Token in der Benutzertabelle, wenn ich mich anmelde, aktualisiere ich ein neues Token und wenn die Authentifizierung gleich dem aktuellen JWT des Benutzers ist.
Ich denke, das ist nicht die beste Lösung, aber das funktioniert für mich.
quelle
Stateless JWT
undStateful JWT
(der Sitzungen sehr ähnlich ist).Stateful JWT
kann von der Pflege einer Token-Whitelist profitieren.