it-swarm.com.de

Verletzen Sitzungen wirklich die RESTfulness?

Verstößt die Verwendung von Sitzungen in einer RESTful-API wirklich gegen RESTfulness? Ich habe viele Meinungen in beide Richtungen gesehen, bin aber nicht davon überzeugt, dass Sitzungen RESTless sind. Aus meiner Sicht:

  • die Authentifizierung ist für RESTfulness nicht untersagt (andernfalls ist die Verwendung von RESTful-Diensten wenig sinnvoll).
  • die Authentifizierung erfolgt durch Senden eines Authentifizierungstokens in der Anforderung, normalerweise im Header
  • dieses Authentifizierungstoken muss auf irgendeine Weise beschafft und widerrufen werden. In diesem Fall muss es erneuert werden
  • das Authentifizierungstoken muss vom Server validiert werden (sonst wäre es keine Authentifizierung).

Wie verletzen Sitzungen dies?

  • clientseitig werden sitzungen mit cookies realisiert
  • cookies sind einfach ein zusätzlicher HTTP-Header
  • ein Sitzungscookie kann jederzeit abgerufen und widerrufen werden
  • sitzungscookies können bei Bedarf eine unendliche Lebensdauer haben
  • die Sitzungs-ID (Authentifizierungstoken) wird serverseitig überprüft

Für den Client ist ein Sitzungscookie genau das gleiche wie jeder andere HTTP-Header-basierte Authentifizierungsmechanismus, außer dass der Cookie -Header anstelle des Authorization -Headers oder eines anderen proprietären Headers verwendet wird. Wenn keine Sitzung mit dem Cookie-Wert serverseitig verbunden wäre, warum würde das einen Unterschied machen? Die serverseitige Implementierung muss den Client nicht betreffen, solange der Server verhält sich RESTful ist. Aus diesem Grund sollten Cookies selbst keine API erstellen RESTless, und Sitzungen sind lediglich Cookies für den Client.

Sind meine Annahmen falsch? Was macht Session-Cookies RESTless?

461
deceze

Definieren wir zunächst einige Begriffe:

  • RESTful:

    Anwendungen, die den in diesem Abschnitt als "RESTful" beschriebenen REST) - Einschränkungen entsprechen, können charakterisiert werden. [15] Wenn ein Dienst eine der erforderlichen Einschränkungen verletzt, kann er nicht als RESTful betrachtet werden.

    nach wikipedia .

  • zustandslose Einschränkung:

    Als Nächstes fügen wir der Client-Server-Interaktion eine Einschränkung hinzu: Die Kommunikation muss zustandslos sein, wie im CSS-Stil (Client-Stateless-Server) in Abschnitt 3.4.3 (Abbildung 5-3), sodass jede Anforderung von Client zu Der Server muss alle Informationen enthalten, die zum Verständnis der Anforderung erforderlich sind, und kann keinen auf dem Server gespeicherten Kontext nutzen. Der Sitzungsstatus bleibt daher vollständig auf dem Client.

    nach der Fielding Dissertation .

Also verstoßen serverseitige Sitzungen gegen die zustandslose Einschränkung von REST und damit auch gegen RESTfulness.

Aus diesem Grund ist ein Sitzungscookie für den Client genau das gleiche wie jeder andere HTTP-Header-basierte Authentifizierungsmechanismus, außer dass der Cookie-Header anstelle des Authorization- oder eines anderen proprietären Headers verwendet wird.

Durch Session-Cookies speichern Sie den Client-Status auf dem Server und damit hat Ihre Anfrage einen Kontext. Versuchen wir, Ihrem System einen Load Balancer und eine weitere Service-Instanz hinzuzufügen. In diesem Fall müssen Sie die Sitzungen zwischen den Dienstinstanzen teilen. Es ist schwer, ein solches System zu warten und zu erweitern, daher ist es schlecht skalierbar ...

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

Aus meiner Sicht:

  • die Authentifizierung ist für RESTfulness nicht untersagt (andernfalls ist die Verwendung von RESTful-Diensten wenig sinnvoll).
  • die Authentifizierung erfolgt durch Senden eines Authentifizierungstokens in der Anforderung, normalerweise im Header
  • dieses Authentifizierungstoken muss auf irgendeine Weise beschafft und 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 Erstellen eines Authentifizierungstokens auf dem Server. Diesen Teil brauchst du nicht. Sie müssen lediglich den Benutzernamen und das Kennwort auf dem Client speichern und bei jeder Anforderung senden. Sie brauchen dazu nicht mehr als HTTP-Basisauthentifizierung und eine verschlüsselte Verbindung:

Figure 1. - Stateless authentication by trusted clients

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

Wahrscheinlich benötigen Sie einen speicherinternen Auth-Cache auf der Serverseite, um die Arbeit zu beschleunigen, da Sie jede Anforderung authentifizieren müssen.

Nun, das funktioniert ziemlich gut bei vertrauenswürdigen Clients, die von Ihnen geschrieben wurden, aber was ist mit Clients von Drittanbietern? Sie können nicht den Benutzernamen und das Kennwort sowie alle Berechtigungen der Benutzer haben. Sie müssen also separat speichern, welche Berechtigungen ein Drittanbieter-Client für einen bestimmten Benutzer haben kann. Auf diese Weise können die Client-Entwickler Drittanbieter-Clients registrieren und einen eindeutigen API-Schlüssel erhalten. Die Benutzer können Drittanbieter-Clients den Zugriff auf einen Teil ihrer Berechtigungen ermöglichen. Wie das Lesen des Namens und der E-Mail-Adresse oder das Auflisten der Freunde usw. Nachdem ein Drittanbieter-Client zugelassen wurde, generiert der Server ein Zugriffstoken. Dieses Zugriffstoken kann vom Drittanbieter-Client verwendet werden, um auf die vom Benutzer erteilten Berechtigungen zuzugreifen.

Figure 2. - Stateless authentication by 3rd party clients

  • Abbildung 2. - Zustandslose Authentifizierung durch Clients von Drittanbietern

Auf diese Weise kann der Drittanbieter-Client das Zugriffstoken von einem vertrauenswürdigen Client (oder direkt vom Benutzer) erhalten. Danach kann eine gültige Anfrage mit dem API-Schlüssel und dem Zugriffstoken gesendet werden. Dies ist der grundlegendste Authentifizierungsmechanismus von Drittanbietern. Weitere Informationen zu den Implementierungsdetails finden Sie in der Dokumentation aller Authentifizierungssysteme von Drittanbietern, z. OAuth. Dies kann natürlich komplexer und sicherer sein. Sie können beispielsweise die Details jeder einzelnen Anforderung auf der Serverseite signieren und die Signatur zusammen mit der Anforderung senden usw. Die tatsächliche Lösung hängt von den Anforderungen Ihrer Anwendung ab.

283
inf3rno

Zunächst einmal ist REST keine Religion und sollte nicht als solche betrachtet werden. Obwohl RESTful-Services Vorteile bieten, sollten Sie nur die Grundsätze von REST) befolgen = soweit sie für Ihre Anwendung sinnvoll sind.

Das heißt, Authentifizierung und clientseitiger Status verstoßen nicht gegen die REST Prinzipien. Während REST erfordert, dass Statusübergänge zustandslos sind, bezieht sich dies auf den Server selbst. At Das Herz von REST handelt von Dokumenten. Die Idee hinter der Zustandslosigkeit ist, dass der SERVER zustandslos ist und nicht die Clients. Jeder Client, der eine identische Anforderung ausgibt (dieselben Header, Cookies, URI usw.). Sollte die Website den aktuellen Standort des Benutzers speichern und die Navigation durch Aktualisierung dieser serverseitigen Navigationsvariablen verwalten, würde REST) verletzt. Ein anderer Client mit identische Anforderungsinformationen werden abhängig vom serverseitigen Status an einen anderen Speicherort übertragen.

Die Webdienste von Google sind ein fantastisches Beispiel für ein RESTful-System. Sie erfordern, dass bei jeder Anforderung ein Authentifizierungsheader mit dem Authentifizierungsschlüssel des Benutzers übergeben wird. Dies verstößt geringfügig gegen die REST Grundregeln, da der Server den Status des Authentifizierungsschlüssels verfolgt. Der Status dieses Schlüssels muss beibehalten werden und es gibt eine Art Ablaufdatum/-zeit, nach der er nicht mehr gültig ist Wie ich oben in meinem Beitrag erwähnte, müssen jedoch Opfer erbracht werden, damit eine Anwendung tatsächlich funktioniert, und die Authentifizierungstoken müssen so gespeichert werden, dass alle möglichen Clients während ihres Aufenthalts weiterhin Zugriff gewähren können Gültige Zeiten: Wenn ein Server den Status des Authentifizierungsschlüssels so lange verwaltet, bis ein anderer Server mit Lastenausgleich die Erfüllung von Anforderungen auf der Grundlage dieses Schlüssels nicht mehr übernehmen kann, haben Sie damit begonnen, die Grundsätze von REST tatsächlich zu verletzen In diesem Fall können Sie ein Authentifizierungstoken, das Sie auf Ihrem Telefon verwendet haben, für den Lastausgleichsserver A verwenden und den Lastausgleichsserver B von Ihrem Desktop aus aufrufen. Sie haben weiterhin Zugriff auf das System und können auf dieselben Ressourcen zugreifen, wenn die Anforderung erfüllt ist Die Wälder waren identisch.

Alles läuft darauf hinaus, dass Sie sicherstellen müssen, dass Ihre Authentifizierungstoken anhand eines Sicherungsspeichers (Datenbank, Cache, was auch immer) validiert werden, um sicherzustellen, dass Sie möglichst viele der REST) beibehalten = Eigenschaften wie möglich.

Ich hoffe, das alles ergab einen Sinn. Sie sollten auch den Abschnitt Einschränkungen des Wikipedia-Artikel über Repräsentationsstatusübertragung lesen, falls Sie dies noch nicht getan haben. Es ist besonders aufschlussreich, wofür die Grundsätze von REST eigentlich sprechen und warum.

326
Jared Harding

Cookies dienen nicht zur Authentifizierung. Warum ein Rad neu erfinden? HTTP verfügt über gut konzipierte Authentifizierungsmechanismen. Wenn wir Cookies verwenden, wird nur HTTP als Transportprotokoll verwendet. Daher müssen wir beispielsweise unser eigenes Signalisierungssystem erstellen, um den Benutzern mitzuteilen, dass sie eine falsche Authentifizierung angegeben haben (dies wäre bei Verwendung von HTTP 401 der Fall) falsch, da wir wahrscheinlich nicht liefern würden Www-Authenticate an einen Client, wie es die HTTP-Spezifikationen erfordern :)). Es sollte auch beachtet werden, dass Set-Cookie ist nur eine Empfehlung für den Kunden. Der Inhalt kann gespeichert werden oder auch nicht (z. B. wenn Cookies deaktiviert sind), während der Header Authorization bei jeder Anforderung automatisch gesendet wird.

Ein weiterer Punkt ist, dass Sie, um ein Autorisierungs-Cookie zu erhalten, wahrscheinlich zuerst Ihre Anmeldeinformationen eingeben möchten. Wenn ja, wäre es dann nicht RESTless? Einfaches Beispiel:

  • Sie versuchen GET /a ohne Cookie
  • Du bekommst irgendwie eine Autorisierungsanfrage
  • Du gehst und autorisierst irgendwie wie POST /auth
  • Du kriegst Set-Cookie
  • Sie versuchen GET /amit Cookie. Aber hat GET /a sich in diesem Fall idempotent verhalten?

Zusammenfassend glaube ich, wenn wir auf eine Ressource zugreifen und uns authentifizieren müssen, müssen wir uns authentifizieren auf derselben Ressource, nirgendwo anders.

12
starteleport

Tatsächlich gilt RESTfulness nur für RESSOURCEN, wie durch eine universelle Ressourcenkennung angegeben. Es ist also nicht wirklich angemessen, über Dinge wie Header, Cookies usw. in Bezug auf REST zu sprechen. REST kann über jedes Protokoll arbeiten, auch wenn dies routinemäßig über HTTP erfolgt.

Der Hauptgrund hierfür ist: Wenn Sie einen REST - Aufruf senden, der eine URI ist, gibt diese URI nach erfolgreichem Aufruf an den Server den gleichen Inhalt zurück, vorausgesetzt, es wurden keine Übergänge durchgeführt (PUT, POST, DELETE)? Bei diesem Test werden Fehler oder Authentifizierungsanforderungen ausgeschlossen, da in diesem Fall die Anforderung noch nicht an den Server gesendet wurde. Dies ist das Servlet oder die Anwendung, die das Dokument zurückgibt, das der angegebenen URI entspricht.

Ebenso können Sie im Fall eines POST oder eines PUT eine bestimmte URI/Nutzlast senden. Unabhängig davon, wie oft Sie die Nachricht senden, werden immer die gleichen Daten aktualisiert, sodass nachfolgende GETs eine zurückgeben gleichbleibendes Ergebnis?

Bei REST handelt es sich um die Anwendungsdaten, nicht um die Informationen auf niedriger Ebene, die erforderlich sind, um diese Daten zu übertragen.

Im folgenden Blog-Beitrag gab 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 fort, und jeder dieser stationären Zustände ist sowohl ein potentieller Startzustand als auch ein potentieller Endzustand. Das heißt, ein RESTful-System ist eine unbekannte Anzahl von Komponenten, die einem einfachen Satz von folgen Regeln so, dass sie immer entweder bei REST sind oder von einem RESTful-Zustand in einen anderen RESTful-Zustand übergehen Jeder Zustand kann durch die darin enthaltenen Darstellungen und die darin bereitgestellten Übergänge mit den Übergängen vollständig verstanden werden Das System kann ein komplexes Zustandsdiagramm sein, aber jeder Benutzeragent kann jeweils nur einen Zustand sehen (den aktuellen stationären Zustand), und daher ist jeder Zustand einfach und kann es sein Ein Benutzer, OTOH, kann jederzeit eigene Übergänge erstellen (z. B. eine URL eingeben, ein Lesezeichen auswählen, einen Editor öffnen usw.). "


Was die Authentifizierung betrifft, unabhängig davon, ob sie über Cookies oder Header erfolgt, hat sie überhaupt nichts mit POST zu tun, solange die Informationen nicht Teil der URI und REST - Nutzdaten sind . In Bezug auf die Staatenlosigkeit sprechen wir also nur über die Anwendungsdaten.

Wenn der Benutzer beispielsweise Daten in einen GUI-Bildschirm eingibt, verfolgt der Client, welche Felder eingegeben wurden, welche nicht, welche erforderlichen Felder fehlen usw. Dies ist alles CLIENT CONTEXT und sollte nicht gesendet oder verfolgt werden vom Server. An den Server werden alle Felder gesendet, die in der IDENTIFIED-Ressource (durch den URI) geändert werden müssen, sodass in dieser Ressource ein Übergang von einem RESTful-Status in einen anderen erfolgt.

Der Client verfolgt also, was der Benutzer gerade tut, und sendet nur logisch vollständige Statusübergänge an den Server.

7
Ken Kopelson

Die HTTP-Transaktion, Basiszugriffsauthentifizierung, ist nicht für RBAC geeignet, da bei der Basiszugriffsauthentifizierung jedes Mal der verschlüsselte Benutzername und das verschlüsselte Kennwort zur Identifizierung verwendet werden. In RBAC wird jedoch die Rolle benötigt, die der Benutzer für einen bestimmten Anruf verwenden möchte. RBAC überprüft keine Berechtigungen für den Benutzernamen, sondern für Rollen.

Sie könnten versuchen, wie folgt zu verketten: usernameRole: password, aber dies ist eine schlechte Praxis, und es ist auch ineffizient, da die Authentifizierungs-Engine, wenn ein Benutzer mehr Rollen hat, alle Rollen in der Verkettung testen müsste, und zwar bei jedem Aufruf erneut. Dies würde einen der größten technischen Vorteile von RBAC zunichte machen, nämlich einen sehr schnellen Autorisierungstest.

Daher kann dieses Problem nicht mithilfe der Standardzugriffsauthentifizierung gelöst werden.

Um dieses Problem zu lösen, ist die Aufrechterhaltung der Sitzung erforderlich, und dies scheint einigen Antworten zufolge im Widerspruch zu REST zu stehen.

Das ist es, was mir an der Antwort gefällt, dass REST nicht als Religion behandelt werden sollte. In komplexen Geschäftsfällen, zum Beispiel im Gesundheitswesen, ist RBAC absolut üblich und notwendig Schade, wenn sie nicht REST verwenden dürften, weil alle REST-Tools-Designer REST als Religion behandeln würden.

Für mich gibt es nicht viele Möglichkeiten, eine Sitzung über HTTP aufrechtzuerhalten. Man kann Cookies mit einer Session-ID oder einen Header mit einer Session-ID verwenden.

Wenn jemand eine andere Idee hat, würde ich mich freuen, sie zu hören.

1
Bert Verhees