553 Stimmen

Verstoßen Sitzungen wirklich gegen RESTfulness?

Ist die Verwendung von Sitzungen in einer RESTful-API wirklich ein Verstoß gegen RESTfulness? Ich habe viele Meinungen gesehen, die in beide Richtungen gehen, aber ich bin nicht überzeugt, dass Sitzungen RESTless . Von meinem Standpunkt aus gesehen:

  • Authentifizierung ist für RESTfulness nicht verboten (sonst gäbe es wenig Nutzen für RESTful-Dienste)
  • Die Authentifizierung erfolgt durch das Senden eines Authentifizierungs-Tokens in der Anfrage, normalerweise in der Kopfzeile
  • dieses Authentifizierungs-Token muss auf irgendeine Weise beschafft werden und kann widerrufen werden; in diesem Fall muss es erneuert werden
  • das Authentifizierungstoken muss vom Server validiert werden (sonst wäre es keine Authentifizierung)

Wie können Sitzungen dagegen verstoßen?

  • client-seitig, Sitzungen werden mit Cookies realisiert
  • Cookies sind einfach ein zusätzlicher HTTP-Header
  • ein Session-Cookie kann jederzeit abgerufen und widerrufen werden
  • Sitzungscookies können bei Bedarf eine unbegrenzte Lebensdauer haben.
  • die Sitzungs-ID (Authentifizierungs-Token) wird serverseitig validiert

Für den Client ist ein Sitzungscookie also genau dasselbe wie jeder andere HTTP-Header-basierte Authentifizierungsmechanismus, außer dass er die Cookie Kopf Kopf Kopf Kopf Kopf an statt der Authorization oder eine andere proprietäre Kopfzeile. Warum sollte es einen Unterschied machen, wenn dem Cookie-Wert serverseitig keine Sitzung zugeordnet ist? Die serverseitige Implementierung braucht den Client nicht zu betreffen, solange der Server verhält sich RESTful. Daher sollten Cookies allein eine API nicht zu einer RESTless und Sitzungen sind einfach Cookies für den Client.

Sind meine Annahmen falsch? Was macht Sitzungscookies RESTless ?

5 Stimmen

Ich habe genau dieses Thema hier behandelt: stackoverflow.com/questions/1296421/rest-complex-applications/

5 Stimmen

Wenn Sie die Sitzung nur zur Authentifizierung verwenden, warum sollten Sie dann nicht die bereitgestellten Header verwenden? Wenn nicht, und Sie die Sitzung für andere Zustände der Konversation verwenden, dann verstößt das gegen die zustandslose Beschränkung von REST.

3 Stimmen

@Will Danke. Es scheint, dass Sie über Sitzungen für die vorübergehende Speicherung der vom Benutzer eingegebenen Daten sprechen, während ich in meinem Fall nur über sie als ein Implementierungsdetail für die Authentifizierung spreche. Könnte dies der Grund für die Unstimmigkeit sein?

363voto

Jared Harding Punkte 4822

Zunächst einmal ist REST keine Religion und sollte auch nicht als solche betrachtet werden. Obwohl RESTful-Dienste Vorteile haben, sollten Sie die Grundsätze von REST nur so weit befolgen, wie sie für Ihre Anwendung sinnvoll sind.

Allerdings verstoßen Authentifizierung und clientseitiger Status nicht gegen die REST-Grundsätze. REST verlangt zwar, dass Zustandsübergänge zustandslos sein müssen, aber dies bezieht sich auf den Server selbst. Im Kern geht es bei REST immer um Dokumente. Die Idee hinter der Zustandslosigkeit ist, dass der SERVER zustandslos ist, nicht die Clients. Jeder Client, der eine identische Anfrage stellt (gleiche Kopfzeilen, Cookies, URI usw.), sollte an dieselbe Stelle in der Anwendung geleitet werden. Wenn die Website den aktuellen Standort des Benutzers speichert und die Navigation durch Aktualisierung dieser serverseitigen Navigationsvariablen verwaltet, würde gegen REST verstoßen. Ein anderer Client mit identischen Anfragedaten würde je nach serverseitigem Zustand an einen anderen Ort geleitet werden.

Die Webdienste von Google sind ein fantastisches Beispiel für ein RESTful-System. Sie verlangen, dass bei jeder Anfrage ein Authentifizierungs-Header mit dem Authentifizierungsschlüssel des Nutzers übergeben wird. Dies verstößt ein wenig gegen die REST-Grundsätze, da der Server den Status des Authentifizierungsschlüssels verfolgt. Der Status dieses Schlüssels muss aufrechterhalten werden, und er hat eine Art Ablaufdatum/-zeit, nach der er keinen Zugriff mehr gewährt. Wie ich jedoch bereits zu Beginn meines Beitrags erwähnt habe, müssen Abstriche gemacht werden, damit eine Anwendung tatsächlich funktionieren kann. Das bedeutet, dass Authentifizierungstoken so gespeichert werden müssen, dass alle möglichen Clients während ihrer Gültigkeitsdauer weiterhin Zugriff gewähren können. Wenn ein Server den Status des Authentifizierungsschlüssels so verwaltet, dass ein anderer Server mit Lastausgleich nicht mehr in der Lage ist, Anfragen auf der Grundlage dieses Schlüssels zu beantworten, verstößt man gegen die Grundsätze von REST. Die Google-Dienste stellen sicher, dass Sie jederzeit ein Authentifizierungs-Token, das Sie auf Ihrem Telefon gegenüber Lastausgleichsserver A verwendet haben, mitnehmen und Lastausgleichsserver B von Ihrem Desktop aus ansprechen können und trotzdem Zugang zum System haben und zu denselben Ressourcen geleitet werden, wenn die Anfragen identisch sind.

Im Endeffekt müssen Sie sicherstellen, dass Ihre Authentifizierungs-Tokens anhand eines Sicherungsspeichers (Datenbank, Cache, was auch immer) validiert werden, um sicherzustellen, dass so viele REST-Eigenschaften wie möglich erhalten bleiben.

Ich hoffe, das alles hat Sinn gemacht. Sie sollten sich auch die Abschnitt Beschränkungen der wikipedia-Artikel zu Representational State Transfer wenn Sie es nicht schon getan haben. Es ist besonders aufschlussreich im Hinblick darauf, wofür die Grundsätze von REST eigentlich sprechen und warum.

337voto

inf3rno Punkte 22107

Lassen Sie uns zunächst einige Begriffe definieren:

  • RESTful:

    Man kann Anwendungen charakterisieren, die den REST-Bedingungen entsprechen beschrieben werden, als "RESTful" bezeichnen.[15] Verletzt ein Dienst eine der der geforderten Einschränkungen verletzt, kann er nicht als "RESTful" bezeichnet werden.

    laut wikipedia .

  • zustandslose Einschränkung:

    Als nächstes fügen wir der Client-Server-Interaktion eine Einschränkung hinzu: Die Kommunikation muss zustandslos sein, wie in der client-stateless-server (CSS) Stil von Abschnitt 3.4.3 (Abbildung 5-3), so dass jede Anfrage vom Client zum Server alle Informationen enthalten muss, die Informationen enthalten muss, um die Anfrage zu verstehen, und nicht auf dem Server gespeicherten Kontext nutzen kann. Der Sitzungsstatus wird daher vollständig auf dem Client gespeichert.

    nach der Fielding-Dissertation .

Serverseitige Sitzungen verletzen also die zustandslose Beschränkung von REST und damit auch die RESTfulness.

Für den Client ist ein Sitzungscookie also genau dasselbe wie jedes anderen HTTP-Header-basierten Authentifizierungsmechanismus, außer dass er den Cookie-Header anstelle des Authorization- oder eines anderen proprietären Header.

Mit Hilfe von Session-Cookies speichern Sie den Client-Status auf dem Server, so dass Ihre Anfrage einen Kontext hat. Versuchen wir nun, einen Load Balancer und eine weitere Service-Instanz zu Ihrem System hinzuzufügen. In diesem Fall müssen Sie die Sessions zwischen den Service-Instanzen teilen. Ein solches System ist schwer zu warten und zu erweitern, so dass es schlecht skaliert...

Meiner Meinung nach ist an Cookies nichts auszusetzen. Die Cookie-Technologie ist ein clientseitiger Speichermechanismus, bei dem die gespeicherten Daten bei jeder Anfrage automatisch an den Cookie-Header angehängt werden. Ich kenne keine REST-Beschränkung, die mit dieser Art von Technologie ein Problem hat. Es gibt also kein Problem mit der Technologie selbst, das Problem liegt in ihrer Verwendung. Fielding schrieb einen Unterabschnitt darüber, warum er HTTP-Cookies für schlecht hält.

Von meinem Standpunkt aus gesehen:

  • Authentifizierung ist für RESTfulness nicht verboten (sonst hätten RESTful-Dienste wenig Sinn)
  • Die Authentifizierung erfolgt durch das Senden eines Authentifizierungs-Tokens in der Anfrage, normalerweise in der Kopfzeile
  • dieses Authentifizierungs-Token muss auf irgendeine Weise beschafft werden und kann widerrufen werden; in diesem Fall muss es erneuert werden
  • das Authentifizierungstoken muss vom Server validiert werden (sonst wäre es keine Authentifizierung)

Ihr Standpunkt war ziemlich solide. Das einzige Problem war das Konzept der Erstellung eines Authentifizierungs-Tokens auf dem Server. Diesen Teil brauchen Sie nicht. Was Sie brauchen, ist das Speichern von Benutzername und Passwort auf dem Client und das Senden bei jeder Anfrage. Dazu braucht man nicht mehr als HTTP Basic Auth und eine verschlüsselte Verbindung:

Figure 1. - Stateless authentication by trusted clients

  • Abbildung 1. - Zustandslose Authentifizierung durch vertrauenswürdige Clients

Sie benötigen wahrscheinlich einen In-Memory-Cache auf der Serverseite, um die Dinge zu beschleunigen, da Sie jede Anfrage authentifizieren müssen.

Bei vertrauenswürdigen Kunden, die von Ihnen geschrieben wurden, funktioniert das recht gut, aber was ist mit Kunden von Dritten? Sie können nicht über den Benutzernamen und das Kennwort und alle Berechtigungen der Benutzer verfügen. Sie müssen also separat speichern, welche Berechtigungen ein Drittanbieter-Client für einen bestimmten Benutzer haben kann. So können die Client-Entwickler ihre Drittanbieter-Clients registrieren und einen eindeutigen API-Schlüssel erhalten, und die Benutzer können den Drittanbieter-Clients den Zugriff auf einen Teil ihrer Berechtigungen erlauben. Wie z.B. das Lesen des Namens und der E-Mail-Adresse, oder das Auflisten der Freunde, etc. Nachdem ein Drittanbieter-Client zugelassen wurde, generiert der Server ein Zugangs-Token. Dieses Zugriffstoken kann vom Drittanbieter-Client verwendet werden, um auf die vom Benutzer gewährten Berechtigungen zuzugreifen, etwa so:

Figure 2. - Stateless authentication by 3rd party clients

  • Abbildung 2. - Zustandslose Authentifizierung durch 3rd-Party-Clients

So kann der Drittanbieter-Client das Zugriffstoken von einem vertrauenswürdigen Client (oder direkt vom Benutzer) erhalten. Danach kann er eine gültige Anfrage mit dem API-Schlüssel und dem Zugangstoken senden. Dies ist der einfachste Authentifizierungsmechanismus für Drittanbieter. Sie können mehr über die Implementierungsdetails in der Dokumentation jedes Drittanbieter-Authentifizierungssystems lesen, z. B. OAuth. Natürlich kann dies komplexer und sicherer sein, z.B. können Sie die Details jeder einzelnen Anfrage auf der Serverseite signieren und die Signatur zusammen mit der Anfrage senden, und so weiter... Die tatsächliche Lösung hängt von den Anforderungen Ihrer Anwendung ab.

13voto

starteleport Punkte 1182

Cookies dienen nicht der Authentifizierung. Warum ein Rad neu erfinden? HTTP verfügt über gut durchdachte Authentifizierungsmechanismen. Wenn wir Cookies verwenden, verwenden wir HTTP nur als Transportprotokoll und müssen daher unsere eigene Signalisierungssystem, zum Beispiel, um den Benutzern mitzuteilen, dass sie eine falsche Authentifizierung angegeben haben (die Verwendung von HTTP 401 wäre nicht korrekt, da wir wahrscheinlich keine Www-Authenticate an einen Client, wie es die HTTP-Spezifikationen verlangen :) ). Es sollte auch beachtet werden, dass Set-Cookie ist nur eine Empfehlung für Kunden. Ihr Inhalt kann gespeichert oder nicht gespeichert werden (z. B. wenn Cookies deaktiviert sind), während Authorization Kopfzeile wird automatisch bei jeder Anfrage gesendet.

Ein weiterer Punkt ist, dass Sie, um ein Autorisierungs-Cookie zu erhalten, wahrscheinlich zuerst irgendwo Ihre Anmeldedaten angeben müssen? Wenn ja, wäre es dann nicht RESTless? Einfaches Beispiel:

  • Sie versuchen GET /a ohne Cookie
  • Sie erhalten irgendwie eine Autorisierungsanfrage
  • Sie gehen und autorisieren irgendwie wie POST /auth
  • Sie erhalten Set-Cookie
  • Sie versuchen GET /a mit Keks. Aber tut GET /a sich in diesem Fall idempotent verhalten?

Zusammenfassend bin ich der Meinung, dass wir uns authentifizieren müssen, wenn wir auf eine Ressource zugreifen und uns authentifizieren müssen für dieselbe Ressource und nicht irgendwo anders.

11voto

Ken Kopelson Punkte 147

Eigentlich gilt RESTfulness nur für RESOURCES, die durch einen Universal Resource Identifier gekennzeichnet sind. Daher ist es nicht wirklich angebracht, über Dinge wie Header, Cookies usw. im Zusammenhang mit REST zu sprechen. REST kann über jedes beliebige Protokoll funktionieren, auch wenn es routinemäßig über HTTP durchgeführt wird.

Der wichtigste Faktor ist folgender: Wenn Sie einen REST-Aufruf senden, bei dem es sich um einen URI handelt, gibt dieser URI, sobald der Aufruf erfolgreich an den Server weitergeleitet wurde, denselben Inhalt zurück, vorausgesetzt, es wurden keine Übergänge (PUT, POST, DELETE) durchgeführt? Dieser Test würde ausschließen, dass Fehler oder Authentifizierungsanfragen zurückgegeben werden, denn in diesem Fall hat die Anfrage noch nicht den Server erreicht, d. h. das Servlet oder die Anwendung, das/die das der angegebenen URI entsprechende Dokument zurückgibt.

Können Sie im Falle eines POST oder PUT einen bestimmten URI/Payload senden und unabhängig davon, wie oft Sie die Nachricht senden, immer dieselben Daten aktualisieren, so dass nachfolgende GETs ein einheitliches Ergebnis liefern?

Bei REST geht es um die Anwendungsdaten, nicht um die Low-Level-Informationen, die für die Übertragung dieser Daten erforderlich sind.

Im folgenden Blogbeitrag gibt Roy Fielding eine schöne Zusammenfassung der gesamten REST-Idee:

http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/5841

"Ein RESTful-System schreitet von einem stationären Zustand zum nächsten in den nächsten, und jeder dieser stationären Zustände ist sowohl ein potenzieller Startzustand und ein potenzieller Endzustand. D.h., ein RESTful-System ist eine unbekannte Anzahl von Komponenten, die einer einfachen Reihe von Regeln gehorchen, so dass sie immer entweder im REST-Zustand sind oder von einem REST-Zustand Zustand in einen anderen RESTful-Zustand übergehen. Jeder Zustand kann vollständig durch die darin enthaltene(n) Darstellung(en) und die Menge der Übergänge verstanden werden, wobei sich die Übergänge auf eine einheitliche Menge von Aktionen beschränkt sind, um verständlich zu sein. Das System kann sein ein komplexes Zustandsdiagramm sein, aber jeder Benutzeragent kann nur jeweils nur einen Zustand sehen (den aktuellen stationären Zustand), so dass jeder Zustand ist einfach und kann unabhängig analysiert werden. Ein Benutzer hingegen, in der Lage, jederzeit eigene Übergänge zu schaffen (z. B. Eingabe eine URL eingeben, ein Lesezeichen auswählen, einen Editor öffnen, usw.)."


Zur Frage der Authentifizierung: Solange die Informationen nicht Teil des URI und der POST-Payloads sind, haben sie mit REST nichts zu tun, ganz gleich, ob sie über Cookies oder Header erfolgen. In Bezug auf die Zustandslosigkeit geht es also nur um die Anwendungsdaten.

Wenn der Benutzer beispielsweise Daten in einen GUI-Bildschirm eingibt, verfolgt der Client, welche Felder eingegeben wurden, welche nicht, welche Pflichtfelder fehlen usw. Dies ist alles KUNDENKONTEXT und sollte vom Server nicht gesendet oder verfolgt werden. Was an den Server gesendet wird, ist der vollständige Satz von Feldern, die in der IDENTIFIZIERTEN Ressource (durch den URI) geändert werden müssen, so dass in dieser Ressource ein Übergang von einem RESTful-Zustand in einen anderen erfolgt.

Der Client behält also im Auge, was der Benutzer tut, und sendet nur logisch vollständige Zustandsübergänge an den Server.

2voto

Ahmet Firat Keler Punkte 254

Nach meinem Verständnis gibt es zwei Arten von Zuständen, wenn es um Sitzungen geht

  • Interaktionsstatus von Client und Server
  • Ressource Staat

Die zustandslose Beschränkung bezieht sich hier auf den zweiten Typ in Rest. Die Verwendung von Cookies (oder lokaler Speicherung) verstößt nicht gegen Rest, da sie sich auf den ersten Typ bezieht.

Fielding sagt: "Jede Anfrage vom Client an den Server muss alle Informationen enthalten, die notwendig sind, um die Anfrage zu verstehen, und kann nicht auf einen gespeicherten Kontext auf dem Server zurückgreifen. Der Sitzungsstatus wird daher vollständig auf dem Client gespeichert.

Dabei geht es darum, dass jede Anfrage, die auf dem Server erfüllt werden soll, alle notwendigen Daten vom Client benötigt. Dies wird dann als zustandslos betrachtet. Und noch einmal, wir reden hier nicht über Cookies, sondern über Ressourcen.

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