Verstößt die Verwendung von Sitzungen in einer RESTful-API wirklich gegen RESTfulness? Ich habe viele Meinungen gesehen, die in beide Richtungen gingen, aber ich bin nicht davon überzeugt, dass Sitzungen RESTlos sind . Aus meiner Sicht:
- Die Authentifizierung ist für RESTfulness nicht verboten (andernfalls würden RESTful-Dienste nur wenig genutzt).
- Die Authentifizierung erfolgt durch Senden eines Authentifizierungstokens in der Anforderung, normalerweise des Headers
- Dieses Authentifizierungstoken muss irgendwie abgerufen werden und kann widerrufen werden. In diesem Fall muss es erneuert werden
- Das Authentifizierungstoken muss vom Server validiert werden (andernfalls wäre es keine Authentifizierung).
Wie verletzen Sitzungen dies?
- Auf der Clientseite werden Sitzungen mithilfe von 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 dasselbe wie jeder andere auf HTTP-Headern basierende Authentifizierungsmechanismus, außer dass der Cookie
Header anstelle des Authorization
oder eines anderen proprietären Headers verwendet wird. Wenn keine serverseitige Sitzung mit dem Cookie-Wert verknüpft wäre, warum würde dies einen Unterschied machen? Die serverseitige Implementierung muss den Client nicht betreffen, solange sich der Server RESTful verhält . Daher sollten Cookies für sich genommen keine API RESTless machen , und Sitzungen sind lediglich Cookies für den Client.
Sind meine Annahmen falsch? Was macht Sitzungscookies RESTless ?
quelle
Antworten:
Definieren wir zunächst einige Begriffe:
RUHIG:
laut wikipedia .
staatenlose Einschränkung:
gemäß der Fielding-Dissertation .
Serverseitige Sitzungen verletzen also die zustandslose Einschränkung von REST und damit auch RESTfulness.
Durch Sitzungscookies speichern Sie den Clientstatus auf dem Server und Ihre Anfrage hat einen Kontext. Versuchen wir, Ihrem System einen Load Balancer und eine weitere Dienstinstanz hinzuzufügen. In diesem Fall müssen Sie die Sitzungen zwischen den Dienstinstanzen freigeben. Es ist schwierig, ein solches System zu warten und zu erweitern, daher skaliert es schlecht ...
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 Probleme mit dieser Art von Technologie 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.
Ihr Standpunkt war ziemlich solide. Das einzige Problem war das Konzept, ein Authentifizierungstoken auf dem Server zu erstellen. Du brauchst diesen Teil nicht. Sie müssen Benutzername und Passwort auf dem Client speichern und bei jeder Anfrage senden. Dazu benötigen Sie nicht mehr als die HTTP-Basisauthentifizierung und eine verschlüsselte Verbindung:
Sie benötigen wahrscheinlich einen speicherinternen Authentifizierungscache auf der Serverseite, um die Arbeit zu beschleunigen, da Sie jede Anforderung authentifizieren müssen.
Das funktioniert bei vertrauenswürdigen Clients, die von Ihnen geschrieben wurden, ziemlich gut, aber was ist mit Clients von Drittanbietern? Sie können nicht den Benutzernamen und das Passwort sowie alle Berechtigungen der Benutzer haben. Sie müssen also separat speichern, welche Berechtigungen ein Drittanbieter-Client für einen bestimmten Benutzer haben kann. So können die Cliententwickler ihre Clients von Drittanbietern registrieren und einen eindeutigen API-Schlüssel erhalten, und die Benutzer können Clients von Drittanbietern den Zugriff auf einen Teil ihrer Berechtigungen ermöglichen. B. das Lesen des Namens und der E-Mail-Adresse oder das Auflisten ihrer Freunde usw. Nachdem der Client eines Drittanbieters zugelassen wurde, generiert der Server ein Zugriffstoken. Diese Zugriffstoken können vom Drittanbieter-Client verwendet werden, um auf die vom Benutzer erteilten Berechtigungen zuzugreifen, z. B.:
Der Client eines Drittanbieters kann das Zugriffstoken also von einem vertrauenswürdigen Client (oder direkt vom Benutzer) erhalten. Danach kann es eine gültige Anfrage mit dem API-Schlüssel und dem Zugriffstoken senden. Dies ist der grundlegendste Authentifizierungsmechanismus von Drittanbietern. Weitere Informationen zu den Implementierungsdetails finden Sie in der Dokumentation jedes Authentifizierungssystems eines Drittanbieters, z. B. 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.
quelle
Erstens ist REST keine Religion und sollte nicht als solche betrachtet werden. RESTful-Services bieten zwar Vorteile, Sie sollten jedoch die Grundsätze von REST nur befolgen, soweit sie für Ihre Anwendung sinnvoll sind.
Die Authentifizierung und der clientseitige Status verstoßen jedoch nicht gegen die REST-Prinzipien. Während REST erfordert, dass Statusübergänge zustandslos sind, bezieht sich dies auf den Server selbst. Im Mittelpunkt von REST stehen Dokumente. Die Idee hinter Staatenlosigkeit ist, dass der SERVER staatenlos ist, nicht die Clients. Jeder Client, der eine identische Anfrage stellt (dieselben Header, Cookies, URI usw.), sollte an dieselbe Stelle in der Anwendung weitergeleitet werden. Wenn die Website den aktuellen Standort des Benutzers speichert und die Navigation durch Aktualisierung dieser serverseitigen Navigationsvariablen verwaltet, wird REST verletzt. Ein anderer Client mit identischen Anforderungsinformationen wird abhängig vom serverseitigen Status an einen anderen Speicherort gebracht.
Die Webdienste von Google sind ein fantastisches Beispiel für ein RESTful-System. Sie erfordern einen Authentifizierungsheader mit dem Authentifizierungsschlüssel des Benutzers, der bei jeder Anforderung übergeben wird. Dies verstößt geringfügig gegen die REST-Prinzipien, 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 kein Zugriff mehr gewährt wird. Wie ich oben in meinem Beitrag erwähnt habe, müssen jedoch Opfer gebracht werden, damit eine Anwendung tatsächlich funktioniert. Authentifizierungstoken müssen jedoch so gespeichert werden, dass alle möglichen Clients während ihrer gültigen Zeiten weiterhin Zugriff gewähren können. Wenn ein Server den Status des Authentifizierungsschlüssels so weit verwaltet, dass ein anderer Server mit Lastenausgleich die Erfüllung von Anforderungen basierend auf diesem Schlüssel nicht übernehmen kann, Sie haben begonnen, die Prinzipien von REST wirklich zu verletzen. Die Dienste von Google stellen sicher, dass Sie jederzeit ein Authentifizierungstoken, das Sie auf Ihrem Telefon verwendet haben, gegen den Lastausgleichsserver A verwenden und den Lastausgleichsserver B von Ihrem Desktop aus aufrufen können und weiterhin Zugriff auf das System haben und zu denselben Ressourcen geleitet werden können, wenn Die Anfragen waren identisch.
Alles läuft darauf hinaus, dass Sie sicherstellen müssen, dass Ihre Authentifizierungstoken gegen einen Sicherungsspeicher (Datenbank, Cache usw.) validiert sind, um sicherzustellen, dass Sie so viele REST-Eigenschaften wie möglich beibehalten.
Ich hoffe, das alles hat Sinn gemacht. Sie sollten auch den Abschnitt Einschränkungen des Wikipedia-Artikels über die Übertragung von Repräsentationszuständen lesen, falls Sie dies noch nicht getan haben. Es ist besonders aufschlussreich, wofür die Grundsätze von REST tatsächlich argumentieren und warum.
quelle
Cookies dienen nicht zur Authentifizierung. Warum ein Rad neu erfinden? HTTP verfügt über gut konzipierte Authentifizierungsmechanismen. Wenn wir Cookies verwenden, verwenden wir HTTP nur als Transportprotokoll. Daher müssen wir ein eigenes Signalisierungssystem erstellen , um beispielsweise den Benutzern mitzuteilen, dass sie eine falsche Authentifizierung angegeben haben (die Verwendung von HTTP 401 wäre falsch, da wir dies wahrscheinlich nicht tun würden Lieferung
Www-Authenticate
an einen Client, wie es die HTTP-Spezifikationen erfordern :)). Es sollte auch beachtet werden, dass diesSet-Cookie
nur eine Empfehlung für den Kunden ist. Der Inhalt kann gespeichert werden oder nicht (z. B. wenn Cookies deaktiviert sind), während derAuthorization
Header bei jeder Anforderung automatisch gesendet wird.Ein weiterer Punkt ist, dass Sie, um ein Autorisierungscookie zu erhalten, Ihre Anmeldeinformationen wahrscheinlich zuerst irgendwo angeben möchten. Wenn ja, wäre es dann nicht RESTless? Einfaches Beispiel:
GET /a
ohne CookiePOST /auth
Set-Cookie
GET /a
mit Cookie. Aber verhältGET /a
sich in diesem Fall idempotent?Zusammenfassend glaube ich, dass wir, wenn wir auf eine Ressource zugreifen und uns authentifizieren müssen, uns auf derselben Ressource authentifizieren müssen , nirgendwo anders.
quelle
Authorization: Basic
oder unterstützenDigest
. Wenn Sie in einem Browserkontext etwas Fortgeschritteneres als Basic- oder Digest-Authentifizierung ausführen möchten (und sollten), benötigen Sie etwas anderes als denAuthorization
Header.GET /a
Ohne Cookie und mit einem Cookie gibt es eindeutig zwei unterschiedliche Anforderungen, und es ist akzeptabel, dass sie sich unterschiedlich verhalten.GET /a
mit Authentifizierungsheader ist auch dasselbe wieGET /a
ohne Authentifizierungsheader, wodurch es für REST gleichermaßen unbrauchbar wird. Wenn Sie einen http-Header anders behandeln als einen anderen, werden Sie dies zumindest ansprechen.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, obwohl dies routinemäßig über HTTP erfolgt.
Die Hauptbestimmung lautet: Wenn Sie einen REST-Aufruf senden, bei dem es sich um einen URI handelt, gibt dieser URI nach erfolgreichem Aufruf des Servers denselben Inhalt zurück, sofern keine Übergänge ausgeführt wurden (PUT, POST, DELETE). ? Dieser Test würde die Rückgabe von Fehlern oder Authentifizierungsanforderungen ausschließen, da die Anforderung in diesem Fall noch nicht an den Server gesendet wurde, dh das Servlet oder die Anwendung, die das dem angegebenen URI entsprechende Dokument zurückgibt.
Können Sie im Fall eines POST oder PUT eine bestimmte URI / Nutzlast senden, und unabhängig davon, wie oft Sie die Nachricht senden, werden immer dieselben Daten aktualisiert, sodass nachfolgende GETs ein konsistentes Ergebnis zurückgeben?
Bei REST geht es um die Anwendungsdaten, nicht um die Informationen auf niedriger Ebene, die für die Übertragung dieser Daten erforderlich sind.
In dem 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 sich immer entweder im REST befinden oder von einem RESTful-Zustand in einen anderen RESTful-Zustand übergehen. Jeder Zustand kann durch die Darstellung (en), die er enthält, und die Menge der Übergänge, die er bereitstellt, vollständig verstanden werden, wobei die Übergänge auf eine Uniform beschränkt sind Eine Reihe von Aktionen, die verständlich sein sollen. 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 unabhängig analysiert werden. A. Der Benutzer OTOH kann jederzeit eigene Übergänge erstellen (z. B. eine URL eingeben, ein Lesezeichen auswählen,öffne einen Editor usw.). "
Beim Thema Authentifizierung, unabhängig davon, ob dies über Cookies oder Header erfolgt, hat die Information, solange sie nicht Teil der URI- und POST-Nutzdaten ist, überhaupt nichts mit REST zu tun. In Bezug auf 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 KUNDENKONTEXT und sollte nicht gesendet oder verfolgt werden vom Server. Was an den Server gesendet wird, ist der vollständige Satz von Feldern, 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 tut, und sendet nur logisch vollständige Statusübergänge an den Server.
quelle
Die HTTP-Transaktion, Basiszugriffsauthentifizierung, ist für RBAC nicht geeignet, da bei der Basiszugriffsauthentifizierung jedes Mal der verschlüsselte Benutzername: Kennwort zur Identifizierung verwendet wird, während in RBAC die Rolle benötigt wird, 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 dass jeder Aufruf erneut. Dies würde einen der größten technischen Vorteile von RBAC zerstören, nämlich einen sehr schnellen Autorisierungstest.
Daher kann dieses Problem nicht mit der Basiszugriffsauthentifizierung gelöst werden.
Um dieses Problem zu lösen, ist die Aufrechterhaltung der Sitzung erforderlich, und dies scheint nach einigen Antworten im Widerspruch zu REST zu stehen.
Das gefällt mir an der Antwort, dass REST nicht als Religion behandelt werden sollte. In komplexen Geschäftsfällen, beispielsweise im Gesundheitswesen, ist RBAC absolut üblich und notwendig. Und es wäre schade, wenn sie REST nicht verwenden dürften, da alle REST-Tool-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 Sitzungs-ID oder einen Header mit einer Sitzungs-ID verwenden.
Wenn jemand eine andere Idee hat, werde ich mich freuen, sie zu hören.
quelle
Ich denke, Token muss alle erforderlichen Informationen enthalten, die darin verschlüsselt sind. Dies ermöglicht die Authentifizierung durch Validierung des Tokens und Dekodierung der Informationen https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/
quelle
quelle