Kannst du mir helfen, das zu verstehen? “Häufige REST-Fehler: Sitzungen sind irrelevant”

Disclaimer: Ich bin neu in der REST-Gedankenschule, und ich versuche, mich darum zu kümmern.

Also, ich lese diese Seite, allgemeine REST-Fehler , und ich habe festgestellt, dass ich völlig verwirrt bin über den Abschnitt über Sitzungen, die irrelevant sind. Dies ist, was die Seite sagt:

Es sollte keinen Client geben, der sich “anmeldet” oder “eine Verbindung startet”. Die HTTP-Authentifizierung wird automatisch bei jeder Nachricht durchgeführt. Client-Anwendungen sind Ressourcenverbraucher, keine Dienste. Deshalb gibt es nichts, wo man sich einloggen kann! Angenommen, Sie buchen einen Flug über einen REST-Webservice. Sie erstellen keine neue “Sitzungs” -Verbindung zum Dienst. Stattdessen bitten Sie das “Ersteller-Objekt für Reiseplaner”, Ihnen einen neuen Reiseplan zu erstellen. Sie können anfangen, die Lücken zu füllen, aber dann eine andere Komponente irgendwo anders im Web bekommen, um einige andere Lücken zu füllen. Es gibt keine Sitzung, daher gibt es kein Problem beim Migrieren des Sitzungsstatus zwischen Clients. Es gibt auch kein Problem mit “Sitzungsaffinität” auf dem Server (obwohl weiterhin Lastverteilungsprobleme bestehen).

Okay, ich bekomme, dass HTTP-Authentifizierung automatisch bei jeder Nachricht erfolgt – aber wie? Wird der Benutzername / das Passwort bei jeder Anfrage gesendet? Erhöht das nicht nur die Angriffsfläche? Ich habe das Gefühl, dass mir ein Teil des Puzzles fehlt.

Wäre es nicht gut, einen REST-Service zu haben, sagen wir /session , der eine GET-Anfrage akzeptiert, bei der ein Benutzername / Passwort als Teil der Anfrage übergeben wird und ein Session-Token zurückgibt, wenn die Authentifizierung erfolgreich war werden dann mit nachfolgenden Anfragen weitergeleitet? Ist das aus REST-Sicht sinnvoll, oder fehlt der Punkt?

Um RESTful zu sein, sollte jede HTTP-Anfrage selbst genügend Informationen enthalten, damit der Empfänger sie vollständig in Übereinstimmung mit der zustandslosen Natur von HTTP verarbeiten kann.

Okay, ich bekomme, dass HTTP-Authentifizierung automatisch bei jeder Nachricht erfolgt – aber wie?

Ja, der Benutzername und das Passwort werden bei jeder Anfrage gesendet. Die gängigsten Methoden hierfür sind die Basiszugriffsauthentifizierung und die Digestzugriffsauthentifizierung . Und ja, ein Lauscher kann die Anmeldeinformationen des Benutzers erfassen. Man würde somit alle gesendeten und empfangenen Daten mittels Transport Layer Security (TLS) verschlüsseln.

Wäre es nicht gut, einen REST-Service zu haben, sagen wir / Session, der eine GET-Anfrage akzeptiert, bei der ein Benutzername / Passwort als Teil der Anfrage übergeben wird und ein Session-Token zurückgibt, wenn die Authentifizierung erfolgreich war werden dann mit nachfolgenden Anfragen weitergeleitet? Ist das aus REST-Sicht sinnvoll, oder fehlt der Punkt?

Dies würde nicht RESTful sein, da es einen Zustand trägt, aber es ist jedoch ziemlich üblich, da es eine Annehmlichkeit für Benutzer ist; Ein Benutzer muss sich nicht jedes Mal anmelden.

Was Sie in einem “Sitzungstoken” beschreiben, wird üblicherweise als Login-Cookie bezeichnet . Zum Beispiel, wenn Sie versuchen, sich in Ihrem Yahoo! Konto gibt es eine Checkbox, die sagt “halte mich für 2 Wochen eingeloggt”. Dies bedeutet im Wesentlichen (in deinen Worten) “halte mein Session Token für 2 Wochen am Leben, wenn ich mich erfolgreich anmelde.” Web-Browser senden solche Anmelde-Cookies (und möglicherweise andere) mit jeder HTTP-Anfrage, die Sie von Ihnen verlangen.

Es ist nicht ungewöhnlich, dass ein REST-Service eine Authentifizierung für jede HTTP-Anforderung erfordert. Amazon S3 erfordert beispielsweise, dass jede Anforderung eine Signatur aufweist, die von den Benutzeranmeldeinformationen, der genauen auszuführenden Anforderung und der aktuellen Uhrzeit abgeleitet wird. Diese Signatur ist auf der Client-Seite leicht zu berechnen, kann vom Server schnell verifiziert werden und ist für einen Angreifer, der sie abfängt, von begrenztem Nutzen (da sie auf der aktuellen Zeit basiert).

Viele Leute verstehen REST-Principales nicht sehr klar. Die Verwendung eines Session-Tokens bedeutet nicht, dass Sie immer Stateful sind. Der Grund für die Übermittlung eines Usernamens / Passworts bei jeder Anfrage ist nur die Authentifizierung und das Senden eines Tokens (generiert durch Login) process) nur um zu entscheiden, ob der Client die Erlaubnis hat, Daten anzufordern oder nicht, verletzen Sie nur REST-Konventionen, wenn Sie entweder Benutzername / Passwort oder Sitzungstoken verwenden, um zu entscheiden, welche Daten angezeigt werden sollen! Stattdessen müssen Sie sie nur für die Authentifizierung verwenden (um Daten anzuzeigen oder um Daten nicht anzuzeigen)

In meinem Fall sage ich JA, das ist RESTy, aber versuche, native PHP-Sitzungen in deiner REST-API zu vermeiden und beginne damit, deine eigenen Hash-Token zu generieren, die in bestimmten Zeitabständen ablaufen!

Nein, es fehlt nicht der Punkt. Googles ClientLogin funktioniert genau so, mit der bemerkenswerten Ausnahme, dass der Client angewiesen wird, mit einer HTTP 401-Antwort zur “/ session” zu gehen. Dadurch wird jedoch keine Sitzung erstellt, sondern Clients können sich (vorübergehend) selbst authentifizieren, ohne die Anmeldeinformationen im Klartext zu übergeben, und der Server kann die Gültigkeit dieser temporären Anmeldeinformationen nach eigenem Ermessen steuern.

Okay, ich bekomme, dass HTTP-Authentifizierung automatisch bei jeder Nachricht erfolgt – aber wie?

“Authorization:” HTTP-Header wird vom Client gesendet. Entweder grundlegend (Klartext) oder Digest.

Wäre es nicht gut, einen REST-Service zu haben, sagen wir / Session, der eine GET-Anfrage akzeptiert, bei der ein Benutzername / Passwort als Teil der Anfrage übergeben wird und ein Session-Token zurückgibt, wenn die Authentifizierung erfolgreich war werden dann mit nachfolgenden Anfragen weitergeleitet? Ist das aus REST-Sicht sinnvoll, oder fehlt der Punkt?

Die ganze Idee der Sitzung besteht darin, statusbehaftete Anwendungen unter Verwendung des statuslosen Protokolls (HTTP) und des dummen Clients (Webbrowsers) zu erstellen, indem der Zustand auf der Serverseite aufrechterhalten wird. Eines der REST-Prinzipien lautet “Jede Ressource ist eindeutig adressierbar unter Verwendung einer universellen Syntax zur Verwendung in Hypermedia-Links” . Sitzungsvariablen sind etwas, auf das nicht über URI zugegriffen werden kann. Eine wahrhaft REST-konforme Anwendung würde den Zustand auf der Clientseite beibehalten und alle erforderlichen Variablen über HTTP senden, vorzugsweise in der URI.

Beispiel: Suche mit Paginierung. Sie hätten eine URL in Form

 http://server/search/urlencoded-search-terms/page_num 

Es hat viel mit Lesezeichen-URLs gemeinsam

Ich denke, dass Ihr Vorschlag in Ordnung ist, wenn Sie die Lebensdauer der Clientsitzung steuern möchten. Ich denke, dass RESTful-Architektur Sie dazu ermutigt, staatenlose Anwendungen zu entwickeln. Wie @ 2pence schrieb: “Jeder HTTP-Request sollte genügend Informationen für sich selbst tragen, damit der Empfänger sie vollständig in Übereinstimmung mit dem Statuslosen HTTP verarbeiten kann.”

Dies ist jedoch nicht immer der Fall. Manchmal muss die Anwendung angeben, wann sich der Client anmeldet oder abmeldet und Ressourcen wie Sperren oder Lizenzen basierend auf diesen Informationen verwaltet. Siehe meine Follow-up- Frage für ein Beispiel für einen solchen Fall.