Teil 2: Vollständige Benutzerauthentifizierung: Sessions vs JWT

Sitzungen und JWT spitzen sich mit einer tieferen Analyse ihrer wahren Komponenten zu: Speicher- und Validierungsstrategie.

Wenn Sie Teil 1 der vollständigen Benutzerauthentifizierung verpasst haben, lesen Sie zunächst einige Grundlagen durch, auf denen wir in Teil 2 aufbauen.

Foto von Koushik Chowdavarapu auf Unsplash

Sessions gegen JWT

So beliebt ein Vergleich auch ist, Sessions vs JWT sind ungenau.

In der Regel werden zwei unterschiedliche, spezifischere Aspekte verglichen: Speicher- und Validierungsstrategie.

Problem 1: Speichermechanismus (Cookies vs. localStorage)

Warum ist Lagerung? Sitzungs-IDs verwenden fast immer Cookies als Speichermechanismus. Diese Beziehung ist allgemein bekannt und in den meisten Sitzungsstrategiesoftwarepaketen (z. B. Node.js Express-Sitzung) vorhanden.

Ein JWT und insbesondere ein Referenz-Token können jedoch auch in einem Cookie gespeichert werden. Sie müssen sich nicht immer in localStorage befinden. Die Unterschiede zwischen Cookies und localStorage sind erheblich, weshalb die Speicherung das erste Anliegen in unserer Aufschlüsselung ist.

Problem 2: Validierungsstrategie (in sich geschlossen gegenüber referenzbasiert)

Warum Validierungsstrategie? Eine Validierungsstrategie, mit der ein Bezeichner (Sitzungs-ID oder Referenz-Token) anhand einer Referenz in einer Datenbank authentifiziert wird, ist eine völlig andere Strategie als eine Strategie, bei der ein JWT verwendet wird, um die Authentifizierung in sich aufzunehmen.

Während eine Sitzungs-ID immer eine referenzbasierte Strategie verwendet, kann ein Token entweder (oder sogar eine Kombination aus beiden) verwenden. Aus diesen Gründen sind unabhängige und referenzbasierte Validierungsstrategien das nächste Problem in unserer Aufschlüsselung.

Zwischen diesen beiden Bedenken bleiben genauere und relevante Vergleiche:

  • Cookies gegen localStorage
  • Validierungsstrategie: In sich geschlossen vs Referenzbasiert

Diese beiden Komponenten einer Authentifizierungsstrategie sollten die Art der verwendeten Kennung oder des verwendeten Tokens bestimmen, nicht umgekehrt.

Diagramm mit der Authentifizierungskennung oder dem Token als Ergebnis der Matrix für bestimmte Bedenken.

Mit mehr Klarheit können wir die gegenüberliegenden Komponenten direkt vergleichen, was uns die Richtung gibt, die wir brauchen, um zu entscheiden, wann wir was verwenden sollen.

Cookies gegen localStorage

Wir haben bereits in Teil 1 einige Grundlagen zum Speichern von Cookies behandelt, aber wir haben noch nicht wirklich über localStorage gesprochen. Was ist localStorage und wie wird es im Authentifizierungskontext mit Cookies verglichen?

localStorage-Grundlagen

LocalStorage ist eine HTML5-Browserspeicherfunktion, mit der eine Website Daten (über den Client) speichern und darauf zugreifen kann.

Um localStorage verwenden zu können, muss das Front-End-JavaScript (Client) der Anwendung die Serverantworten verarbeiten und die Daten, die in localStorage gespeichert werden sollen, manuell schreiben. Im Gegensatz zu Cookies erhält der Server über HTTP-Header nicht automatisch Zugriff auf den Speichermechanismus.

Um Daten an den Server zu senden, muss der Client den localStorage lesen und die gewünschten Daten in einer Anforderung manuell festlegen.

Obwohl der Client die Arbeit manuell erledigen muss (im Gegensatz zu Cookies), sind diese Vorgänge mit der Web Storage-API äußerst einfach:

localStorage.setItem ("authToken", authToken);
let authToken = localStorage.getItem ("authToken");

LocalStorage ist in allen Fenstern / Registerkarten für denselben Ursprung (Domäne) verfügbar. LocalStorage hat auch kein Ablaufdatum. Diese beiden Funktionen stehen im Gegensatz zu der Geschwisterfunktion sessionStorage, einer weiteren HTML5-Webspeicherfunktion.

SessionStorage bleibt nicht über mehrere Registerkarten hinweg bestehen und wird gelöscht, wenn die Sitzung (Registerkarte) geschlossen wird. LocalStorage wird in der Regel anstelle von sessionStorage für Token ausgewählt, da mehrere Registerkarten / Fenster vorhanden sind, was zu einer besseren Benutzererfahrung führt.

Wenn sessionStorage verwendet wurde und ein bereits authentifizierter Benutzer die Anwendung auf einer neuen Registerkarte öffnet, stellt er fest, dass er auf der neuen Registerkarte nicht authentifiziert ist. Dies ist kein typisches Verhalten einer Webanwendung, aber diese Nicht-Persistenz kann für etwas Zeitlicheres wie einen Bestellfluss erwünscht sein.

Cookies vs. localStorage: Authentifizierung vom Client stehlen (XSS)

Ein wichtiges Sicherheitsproblem des Authentifizierungsspeichers besteht darin, den Diebstahl zu verhindern, was normalerweise zur Entführung einer Sitzung führt.

Ein häufiger Angriff zum Diebstahl der Authentifizierung ist ein Cross-Site Scripting-Angriff (XSS). Das Endergebnis eines erfolgreichen XSS-Angriffs ist die Fähigkeit eines Angreifers, JavaScript im Namen des Benutzers auszuführen. Grundsätzlich hat der Angreifer die vollständige Kontrolle über den Client.

Die Daten in einem Cookie können vor einem erfolgreichen XSS-Angriff geschützt werden, wenn die Cookie-Einstellung HttpOnly verwendet wird, wodurch verhindert wird, dass Client-JavaScript das Cookie lesen kann. Ein Cookie ohne diese Einstellung wäre jedoch anfällig.

LocalStorage ist für einen erfolgreichen XSS-Angriff anfällig, da localStorage immer über das Client-JavaScript zugänglich ist.

Das bloße Schützen der Authentifizierungskennung oder des Tokens vor einem XSS-Angriff mit einem Cookie verhindert jedoch nicht das Auftreten anderer schwerwiegender Angriffe, z. B. das Umgehen des Schutzes vor Fälschungsangriffen (CSRF) oder das Protokollieren von Schlüsseln.

Es ist daher wichtig, XSS in jeder Situation immer direkt zu bekämpfen, unabhängig vom verwendeten Speichergerät - Cookie oder auf andere Weise.

Es gibt leider keine schnelle Lösung für die Verhinderung von XSS-Schwachstellen, und es ist ein umfassendes Verständnis der potenziellen Probleme, bewährten Methoden, Verhinderungstechniken (Inhaltssicherheitsrichtlinie) und laufenden Tests erforderlich, um diese Angriffe zu verhindern.

Ähnlich wie bei einem XSS-Angriff müssen sich Netzwerke wie Facebook mit böswilligen Websites befassen, die behaupten, Benutzern, die einen Code in ihren Inspektor kopieren / einfügen und das Ergebnis (z. B. in der Regel die eigenen Authentifizierungsdetails des Benutzers) erneut kopieren / einfügen, besondere Funktionen zu bieten die Website des Angreifers. Diese Art von Social-Engineering-Angriff auf Authentifizierungsdetails wird mit localStorage erleichtert, da die HttpOnly-Cookie-Daten geschützt sind.

Schließlich können Authentifizierungsdetails auch über nicht sichere (https) Anforderungen gestohlen werden - ein Man-in-the-Middle-Angriff, der über öffentliches WLAN verbreitet ist. Dies kann sowohl localStorage als auch Cookies betreffen. Das Erzwingen von https (mit 301-Weiterleitungen und HSTS) für alle Anforderungen und die Verwendung der Cookie-Einstellung "Sicher" tragen dazu bei, Man-in-the-Middle-Angriffe zu verhindern.

Fazit: Cookies haben hier nur einen geringen Vorteil gegenüber localStorage, solange sie die entsprechenden Einstellungen vornehmen (HttpOnly, secure). Es ist jedoch wichtig zu beachten, dass ein erfolgreicher XSS-Angriff zu einer Reihe schwerwiegender Probleme führen kann.

Cookies vs. localStorage: Serverseitige Anfragen mit Authentifizierung (CSRF) fälschen

Ein weiteres wichtiges Sicherheitsproblem beim Speichern besteht darin, zu verhindern, dass die gespeicherte Authentifizierung verwendet wird, um serverseitige Anforderungen im Namen des Benutzers zu fälschen, ohne dass der Benutzer dies weiß.

Beispielsweise könnte eine Anfrage im Namen eines bereits authentifizierten Benutzers gesendet werden, das Kennwort dieses Benutzers zurückzusetzen oder eine Zahlung des Benutzers an attacker@somedomain.com zu senden.

Diese Art von Angriff wird als CSRF-Angriff (Cross-Site Request Forgery) bezeichnet. Der Angriff wird ausgeführt, indem authentifizierte Anfragen im Namen eines Benutzers an eine Website gerichtet werden, auf der er gerade angemeldet ist. Der Angriffsvektor kann in Form eines umsetzbaren Links auf der Website, auf die der Benutzer klickt, eines in böswilliger Absicht gehosteten Formulars, das der Benutzer übermittelt, oder eines in böswilliger Absicht gehosteten XHR-Skripts vorliegen, das der Benutzer besucht.

Da ein Browser automatisch die Cookie-Authentifizierung in den HTTP-Headern bereitstellt, ist die von Cookies bereitgestellte Authentifizierung für diese Art von Angriff anfällig. Die LocalStorage-Authentifizierung ist nur dann für CSRF anfällig, wenn HTTP-Methoden nicht ordnungsgemäß verwendet werden.

Insbesondere wurde festgelegt, dass die Methoden GET und HEAD NICHT die Bedeutung haben DÜRFEN, eine andere Aktion als das Abrufen durchzuführen.

Die Verhinderung von CSRF-Angriffen für die von Cookies bereitgestellte Authentifizierung erfolgt in der Regel in Form von Synchronisierungstoken (von OWASP empfohlen), der Einstellung für SameSite-Cookies und / oder der Verwendung der Richtlinie des Browsers für identische Herkunft (bei Verwendung von Serverendpunkten, auf die nur über XHR zugegriffen werden kann). . Ich empfehle ein gründliches Lesen des OWASP CSRF Prevention Cheat Sheet.

Da ein Synchronizer-Token (oder CSRF-Token) normalerweise in localStorage gespeichert ist, kann der Angreifer bei einem erfolgreichen XSS-Angriff auch XHR-Anforderungen mit dem Synchronizer-Token vom Ursprung aus senden.

Jede Cross-Site-Scripting-Sicherheitsanfälligkeit kann verwendet werden, um alle derzeit auf dem Markt verfügbaren CSRF-Abwehrtechniken zu beseitigen (mit Ausnahme von Abwehrtechniken, die Benutzerinteraktion beinhalten und später in diesem Cheatsheet beschrieben werden).

Fazit: LocalStorage hat hier einen Vorteil gegenüber Cookies, da es nicht für CSRF-Angriffe anfällig ist, solange HTTP-Methoden für die Bearbeitung von Anforderungen korrekt verwendet werden.

Cookies vs. localStorage: Implementierungsschwierigkeiten

Da Cookies für CSRF-Angriffe anfällig sind, muss zusätzliche Arbeit in die Implementierung von Präventionstechniken gesteckt werden. Und XSS-Schwachstellen müssen in beiden Szenarien (Cookies oder localStorage) immer geschützt werden.

Allerdings erfordert localStorage die manuelle Behandlung (Client / JavaScript) der Authentifizierung von der Antwort über die Speicherung bis zur Anforderung.

Wenn Sie in sich geschlossene Authentifizierungstoken (JWT) verwenden, muss auch eine Middleware eingerichtet werden, um fortlaufende Verfallsdaten für jede Anforderung zu verarbeiten.

Wenn wir Datenbankspeicher für Token / Sitzungen verwenden, kann es im Vergleich zu Drop-In-Datenbanklösungen für die cookiebasierte Authentifizierung auch schwieriger werden, Token über localStorage zu verwalten.

Fazit: Cookies gewinnen hier, wenn die Authentifizierungsstrategie eine Datenbank erfordert, ansonsten aber beide spezifische Implementierungsanforderungen haben.

Cookies im Vergleich zu localStorage: Single-Page-Anwendungen (SPA), API-Server und Microservices

Bei der Kommunikation mit einem API-Server in einer von einem Client getrennten Domäne (im Fall eines SPA) ist die gemeinsame Nutzung von Ressourcen über verschiedene Herkunftsländer (Cross-Origin Resource Sharing, CORS) erforderlich. Die Kommunikation der Authentifizierung über CORS ist mit localStorage etwas einfacher, mit Cookies jedoch weiterhin möglich (mithilfe von XHR mit Berechtigungsnachweisen und Antwort-Headern für die Zugriffskontrolle).

In diesem Fall muss für die Verwendung von Cookies (sog. "Drittanbieter-Cookies") eine Ursprungs-Whitelist geführt werden, da der Platzhalter "Zugriffskontrolle-Zulassen-Ursprung" (*) beim Übergeben von Cookies nicht zulässig ist. Zwar ist es möglich, dass die Verwendung von Cookies von Drittanbietern zur Authentifizierung aufgrund von Taktiken (z. B. Safari ITP) problematisch wird, die verhindern sollen, dass Cookies von Werbetreibenden (auch von Drittanbietern) nachverfolgt werden. Es ist daher möglicherweise weniger ratsam, sich in Zukunft auf Cookies von Drittanbietern zu verlassen.

Einige Benutzerprogramme beschränken das Verhalten von Cookies von Drittanbietern. Einige dieser Benutzeragenten lehnen es beispielsweise ab, den Cookie-Header in Anfragen von Drittanbietern zu senden. Andere lehnen es ab, den Set-Cookie-Header in Antworten auf Anfragen von Drittanbietern zu verarbeiten.

Wenn dieselbe Authentifizierung an mehrere Back-End-Dienste / APIs in unterschiedlichen Domänen übergeben werden muss, wird die Verwendung von Cookies schwierig. Wenn beispielsweise sowohl microservice-A.com als auch microservice-B.com Zugriff auf dasselbe HttpOnly-Authentifizierungscookie benötigen, ist dies ein Problem. Es gibt einige Lösungen für dieses Problem (z. B. Proxy, ausgeblendete Iframes), aber sie erhöhen die Komplexität.

Als Randnotiz ist es möglich, dass ein HttpOnly-Cookie über mehrere Unterdomänen hinweg (unter Verwendung derselben Domain) verwendet wird, was nicht als Cookie eines Drittanbieters gilt. Damit ein Cookie in mehreren Subdomains verwendet werden kann, muss die Domain-Einstellung des Cookies konfiguriert werden.

Die Verwendung von localStorage ist von diesen Problemen nicht betroffen, da das Client-JavaScript die localStorage-Daten jedoch an jeden beliebigen Ort senden kann.

Fazit: LocalStorage hat große Vorteile, wenn dieselbe Authentifizierung für mehrere Microservices in unterschiedlichen Domänen erforderlich ist. LocalStorage gewinnt auch, wenn eine Authentifizierung über eine Drittanbieter-API in einer vom Client getrennten Domäne erforderlich ist. Wenn Sie jedoch nur einen Client zur Authentifizierung bei einem API-Server in derselben Domäne (oder Unterdomäne) benötigen, funktionieren Cookies oder localStorage.

Cookies vs. localStorage: Schlussbemerkung

Bei den meisten herkömmlichen und einfacheren Webanwendungen ist das Speichern von Cookies aufgrund der in den meisten Authentifizierungspaketen enthaltenen Standardfunktionalität etwas einfacher zu implementieren als localStorage. Dies gilt insbesondere dann, wenn in der Strategie eine Datenbank erforderlich ist.

Wenn jedoch eine Architektur erforderlich ist, bei der dieselbe Authentifizierung für mehrere Dienste in verschiedenen Domänen oder nur in einer vom Client getrennten Domäne bereitgestellt wird, ist localStorage ein einfacher Gewinner.

In Bezug auf die Sicherheit müssen alle XSS-, CSRF- und MIM-Angriffe mithilfe korrekter Techniken verhindert werden, wenn Cookies oder localStorage verwendet werden. Nur die Verwendung von Cookies verhindert XSS nicht und nur die Verwendung von localStorage verhindert CSRF nicht vollständig.

Unabhängige oder referenzbasierte Authentifizierung

Wenn Sie sich früher an Teil 1 erinnern, kann, obwohl in einer referenzbasierten Authentifizierungsstrategie fast immer eine Sitzungs-ID verwendet wird, eine JWT verwendet werden - eine referenzbasierte oder eine eigenständige Strategie.

Da Token in beiden Arten von Validierungsstrategien verwendet werden können, werden diese Validierungsstrategien direkt verglichen: die herkömmliche Referenz-basierte Identifizierungsstrategie mit der derzeit im Trend befindlichen Strategie der unabhängigen Authentifizierung (mit JWT).

In sich geschlossen vs. referenziert: Staatenlosigkeit und REST

Das zustandslose Protokoll ist ein Kommunikationsprotokoll, bei dem weder vom Absender noch vom Empfänger Informationen gespeichert werden.

Das Konzept der Staatenlosigkeit für Webdienste begann als eine von sechs wichtigen Entwurfsbeschränkungen in einem Architekturstil zum Erstellen von Webdiensten, der als Representational State Transfer (REST) ​​bezeichnet wird. Diese Einschränkungen wurden bereits früher beim Entwerfen von HTTP-Standards verwendet (HTTP ist zustandslos).

Der Begriff Repräsentationsstaatstransfer wurde im Jahr 2000 von Roy Fielding in seiner Dissertation eingeführt und definiert. In der Dissertation von Fielding wurden die REST-Prinzipien erläutert, die ab 1994 als "HTTP-Objektmodell" bekannt waren und beim Entwurf der Standards HTTP 1.1 und Uniform Resource Identifiers (URI) verwendet wurden.

Was genau bedeutet es für Web Services, staatenlos zu werden?

Zustandslosigkeit bedeutet, dass jede HTTP-Anforderung vollständig isoliert erfolgt. Wenn der Client eine HTTP-Anfrage stellt, enthält er alle Informationen, die der Server benötigt, um diese Anfrage zu erfüllen. Der Server verlässt sich niemals auf Informationen aus früheren Anfragen. Wenn diese Informationen wichtig wären, hätte der Kunde sie in dieser Anfrage erneut gesendet. ("RESTful Web Services", 2007)

Ein Beispiel für eine zustandsbehaftete und zu vermeidende Situation ist eine Situation, in der ein Kunde die Suchergebnisse seitenweise durchblättern muss, um sie zu vermeiden. Ein zustandsloser Ansatz würde es dem Kunden jedoch ermöglichen, eine beliebige Seite der Ergebnisse anzufordern, ohne eine bestimmte Reihenfolge einhalten zu müssen.

Um dieses Problem der Adressierbarkeit von Ressourcen zu lösen, wird das zustandslose Design in den meisten modernen Webdiensten gern verwendet. Die vollständige Konformität mit dem statusfreien Client-Server-Design stellt jedoch Probleme bei referenzbasierten Authentifizierungsstrategien dar, da der Server laut REST keine Informationen zur Benutzersitzung einschließlich einer Authentifizierungskennung haben / speichern kann.

Eine referenzbasierte Authentifizierungsstrategie verstößt gegen Staatenlosigkeit.

In einem Ressourcenadressierbarkeitskontext ist Zustandslosigkeit sinnvoll, aber warum ist es für die Authentifizierung oder Sitzungen wichtig? Und spielt es eine Rolle, dass eine referenzbasierte Authentifizierung die Staatenlosigkeit verletzt?

Durch die Verwendung eines zustandslosen Protokolls und von Standardvorgängen streben REST-Systeme eine schnelle Leistung, Zuverlässigkeit und Wachstumsfähigkeit an, indem Komponenten wiederverwendet werden, die verwaltet und aktualisiert werden können, ohne das System als Ganzes zu beeinträchtigen, auch wenn es ausgeführt wird.

Die wichtigsten Erkenntnisse (und typischen Argumente) im Zusammenhang mit der Staatenlosigkeit bei der Authentifizierung sind Geschwindigkeit und Skalierbarkeit.

Das Skalieren einer Webanwendung zur Unterstützung einer großen Anzahl von gleichzeitigen Anforderungen oder aktiven Sitzungen war traditionell ein Problem bei der Sitzungsverwaltung.

Wenn Sie ein JWT verwenden, um die Authentifizierung in sich aufzunehmen, befindet sich die Authentifizierung vollständig im Client und es ist nicht mehr erforderlich, den Clientstatus (in diesem Fall die Authentifizierungskennung) auf dem Server zu speichern.

Es ist allgemein anerkannt, dass eine in sich geschlossene JWT die Zustandslosigkeitsanforderungen von REST erfüllt, was für sich genommen zu einem Argument für die Verwendung einer in sich geschlossenen JWT geworden ist.

Ich verwende die allgemein akzeptierte Formulierung, da Fielding die zustandslose Authentifizierung in seiner Dissertation zu REST nicht direkt abdeckt. Die Dissertation befasst sich eher mit Staatenlosigkeit im Kontext der Adressierbarkeit von Ressourcen.

Es sollte auch beachtet werden, dass der Versuch, JWTs - eine allgemeine Sicherheitsanforderung - von einer laufenden Blacklist oder einem Versionssystem aus für ungültig zu erklären, wahrscheinlich die Zustandslosigkeitsanforderung verletzt. Weniger die schwarze Liste, aber der Server speichert weiterhin Clientstatus- / Sitzungsdaten. Eine Blacklist implementiert auch das Gegenteil eines idealen Sicherheitsdesigns - die Verwendung einer Whitelist anstelle einer Blacklist.

Zurück zur referenzbasierten Authentifizierung: Bei Verwendung von skalierbarem Cloud-basiertem In-Memory-Schlüsselwertspeicher (z. B. Redis) ist die Erhöhung der Sitzungsanzahl für die meisten Anwendungen kein Problem. Geschwindigkeit und Skalierbarkeit spielen bei einer referenzbasierten Authentifizierungsstrategie keine Rolle mehr.

Dann bleibt die Frage, wie wichtig es ist, die REST-Einschränkungen genau einzuhalten, und kann es bei der Authentifizierung Flexibilität geben?

Wenn wir uns ansehen, wie beliebte Unternehmen REST in ihren Webdiensten verwenden, stellen wir häufig einen Verstoß gegen die strikte zustandslose Konformität fest. Bei gängigen Webdiensten werden in der Regel API-Schlüssel, Cookies, in Datenbanken gespeicherte Token oder eine andere Form der statusbehafteten Authentifizierungskennung verwendet. In der Regel auch aus guten Gründen - Widerruf, Nutzungsverfolgung, verschiedene Analysezwecke, Ratenbegrenzung usw.

Die Entscheidung, sich an REST oder sogar an REST zu halten, hat sich unter Entwicklern zu einem religiösen Argument entwickelt.

Denken Sie daran, dass REST ein Stil ist, kein Standard. Wenn Sie einen RESTful-Webdienst erstellen, ist es wichtig, die Gründe für die Verwendung der Einschränkungen und insbesondere für die zustandslose Authentifizierung gegen die Gründe abzuwägen, warum dies nicht der Fall ist.

REST ist Software-Design im Maßstab von Jahrzehnten: Jedes Detail soll die Langlebigkeit der Software und die unabhängige Weiterentwicklung fördern. Viele der Einschränkungen stehen der kurzfristigen Effizienz direkt entgegen. - Roy Fielding

Fazit: Kein Gewinner hier. Unter REST unterbricht die referenzbasierte Authentifizierung die Zustandslosigkeit - eine der sechs Entwurfsbeschränkungen. Bei einem eigenständigen JWT ist dies nicht der Fall, sondern nur, solange keine anderen Clientinformationen gespeichert werden, um auf eine nachfolgende Antwort zu reagieren. Dies ist in den meisten Produktionsumgebungen und Geschäftsfällen ein unwahrscheinliches Szenario.

Geschwindigkeit und Skalierbarkeit für das Sitzungsmanagement (Vorteile der Statuslosigkeit) sind dank moderner Cloud-basierter Datenspeicherlösungen auch für die meisten Anwendungen kein Problem mehr.

Autark vs. Referenziert: Geschwindigkeit

Ein weiteres Argument für die Verwendung eines JWT und einer in sich geschlossenen Authentifizierung ist, dass es schneller ist als eine referenzbasierte Strategie. Es ist nicht erforderlich, die Sitzungs-ID nachzuschlagen. Und wenn das JWT auch alle Benutzerdaten enthält, muss der Benutzer nicht einmal nachgeschlagen werden.

Wenn Sie alle Benutzerdaten in einem JWT speichern, können Sie eine Vielzahl anderer Probleme lösen, darunter:

  • Weitere Sicherheitsbedenken, wenn die JWT gestohlen wird.
  • Probleme mit der Größe des Datenspeichers
  • Persistenz- und Verfügbarkeitsprobleme (mehr technische Probleme)

Zweitens fügen diese Datenbankaufrufe der Anforderung Mikrosekunden hinzu.

Es muss ein Zuverlässigkeitsargument angeführt werden (ein Vorteil der Staatenlosigkeit), aber die Verfügbarkeit ist weitaus weniger ein Problem als vor Jahren.

Fazit: Kein Gewinner hier. Geschwindigkeitssteigerungen sind für die meisten Anwendungen kein Problem. Der Engineering-Aufwand und das Risiko, sich auf ein Token zu verlassen, um einen Benutzerdatensatz für die Dauer einer Sitzung bereitzustellen, überwiegen in den meisten Situationen die Vorteile.

Eigenständig vs. referenziert: Invalidierung

Ein allgemeines Sicherheitsrisiko für jedes Authentifizierungssystem besteht darin, aktive Sitzungen für ungültig zu erklären, falls dies erforderlich sein sollte.

Das Inaktivieren der referenzbasierten Authentifizierung ist einfach - suchen Sie die Sitzung und löschen Sie sie aus der Datenbank.

Leider ist das Ungültigmachen einer in sich geschlossenen Authentifizierung nicht so einfach.

Zwei gebräuchliche Methoden hierfür sind die Verwendung einer laufenden schwarzen Liste von Tokens oder das Hinzufügen einer Version im JWT (als Teil der signierten Ansprüche) und das Vergleichen der Version mit einer im Benutzerdatensatz der Datenbank gespeicherten Version.

Beide Lösungen sorgen jedoch für mehr Engineering, unterbrechen die Zustandslosigkeit und / oder heben Geschwindigkeitsgewinne auf.

Fazit: Ein Gewinn für die referenzbasierte Authentifizierung. Die Invalidierung ist wichtig, und eine in sich geschlossene JWT erschwert dies.

In sich geschlossen oder referenziert: Analytics and Tracking

Eine häufige Anforderung für die meisten Authentifizierungssysteme ist es, Benutzergewohnheiten nachverfolgen zu können…

  • Wie oft meldet sich ein Benutzer an?
  • Wie viele Benutzer sind zu bestimmten Zeiten angemeldet?
  • Wie lang ist die durchschnittliche Benutzersitzung?
  • Wie viele Anfragen kann / hat eine Sitzung in einem bestimmten Zeitraum gestellt?

Etc. etc.

Während einige davon mit einer in sich geschlossenen JWT zu tun haben, wird diese Funktionalität durch referenzbasierte Authentifizierungsstrategien erleichtert, da der Sitzungsdatenspeicher bereits einen Großteil der Informationen enthält, die für die Analyse und Nachverfolgung erforderlich sind.

Fazit: Ein kleiner Gewinn für die referenzbasierte Authentifizierung.

Eigenständig oder referenziert: Mobil / gerätefreundlich

Ich würde argumentieren, dass eine referenzbasierte Strategie für einen einfachen, aber beliebten Anwendungsfall tatsächlich mehr für mehrere Geräte als eine JWT-Strategie geeignet ist: Eine referenzbasierte Strategie ermöglicht es einem Benutzer, zu wissen, bei welchen Geräten er derzeit angemeldet ist.

Mit einem in sich geschlossenen JWT ist dies viel schwieriger.

Fazit: Ein kleiner Gewinn für die referenzbasierte Authentifizierung.

In sich geschlossen vs. referenziert: Schlussbemerkung

Eine referenzbasierte Lösung ist einfacher zu implementieren und bietet die Möglichkeit, diese Anforderungen einfacher zu erweitern. Die Skalierbarkeit von Sitzungsdatenspeichern ist heutzutage dank moderner Cloud-basierter Datenspeicherlösungen weniger problematisch.

Die REST-Anforderungen für die Zustandslosigkeit in einem Authentifizierungskontext sind nicht immer klar - gilt die Verwendung eines benutzerspezifischen JWT-Geheimnisses immer noch als zustandslose Interaktion oder wird das gespeicherte Geheimnis auch als "gespeicherter Kontext" betrachtet? Wenn nicht, wo befindet sich die zustandslose Linie zwischen ein Anwendungsgeheimnis und ein in einer Datenbank gespeichertes Geheimnis?

Wenn man sich auf die Vorteile der Staatenlosigkeit konzentriert (Sichtbarkeit, Zuverlässigkeit, Geschwindigkeit und Skalierbarkeit), scheint die Adressierbarkeit von Ressourcen wichtiger zu sein.

Schlussfolgerungen für die Benutzerauthentifizierung

Wir haben viel durchgemacht! Und im Authentifizierungsbereich ist immer mehr los (HTTP-Headersignaturen, OpenId usw.).

Wenn Sie jedoch einige der detaillierteren Elemente kennen, können Sie eine solide Authentifizierungsstrategie für Ihre Anwendung entwickeln.

Daher meine Zusammenfassung der persönlichen Empfehlungen für die meisten Anwendungen:

  • Halten Sie sich an eine Referenzstrategie für die Benutzerauthentifizierung. Es ist einfacher, mit den aktuellen Datenspeicherlösungen zu arbeiten, und die Skalierbarkeit ist für die meisten Anwendungen kein großes Problem mehr. Die Verwendung eines JWT für die in sich geschlossene Authentifizierung ist in Ordnung, Sie sollten jedoch einen guten Grund dafür haben (möglicherweise Single Sign-On).
  • Zustandslosigkeit (eine Einschränkung von REST) ​​für Authentifizierung und Adressierbarkeit sind zu gemischten Bedenken geworden, und REST hat sich zu einem Modewort entwickelt, das sich normalerweise nur auf eine einzelne und teilweise Implementierung des REST-Stils bezieht. Untersuchen Sie immer die zugrunde liegenden Gründe für die Verwendung eines Stils oder eines Elements eines Stils.
  • Wenn Sie eine komplexe Dienstarchitektur haben, möchten Sie möglicherweise localStorage verwenden. Es wird ein wenig mehr Arbeit erfordern, aber Sie werden weniger wachsende Schmerzen haben. Cookies sind anfangs nicht so einfach einzurichten, können sich aber später als problematisch erweisen, wenn Sie Ihre Dienste horizontal skalieren müssen.
  • Die Verwendung von Cookies kann CSRF-Probleme verursachen, und es sollte eine Strategie festgelegt werden, um dies zu verhindern. XSS ist eine potenzielle Bedrohung, unabhängig davon, ob Sie Cookies oder localStorage verwenden. Sowohl XSS als auch CSRF sollten jedoch unabhängig von Ihrem Speichermechanismus behandelt werden.
  • Stellen Sie sicher, dass Sie HTTPS erzwingen, um MIM-Angriffe zu verhindern.

Vielen Dank! Bitte kommentieren Sie unten, folgen Sie mir (Nick Jagodzinski) oder geben Sie ein paar , wenn Sie diese Artikel nützlich fanden. Senden Sie auch einen Kommentar, wenn Sie Fragen haben, Dinge, die ich verpasst habe, Ideen oder Meinungen!