Ich baue eine einfache API mit django-tastypie. Die Idee ist, dass ich zwei Ressourcen habe:
TL; DR: Ich kann die Bearbeitung von Notizen nicht auf den Ersteller eines Hinweises beschränken, während ich einem Benutzer dennoch erlauben kann, einen Hinweis zu kommentieren.
Ich verwende das folgende Setup für die Authentifizierung:
%Vor%Kurz gesagt, ein Benutzer ist nur berechtigt, Objekte zu bearbeiten, für die er der Eigenschaft created_by entspricht (er kann nur die Objekte bearbeiten, die er erstellt hat).
Dies ist wie folgt verknüpft:
%Vor% Wenn Sie also ein Objekt erstellen, wird der aktuelle Benutzer automatisch an das Attribut created_by
angehängt und mit der entsprechenden Berechtigung verknüpft.
Eine Comment
Ressource ist einfach und hat nur eine ForeignKey
zu einer Note
Ressource.
Das Problem ist das: Wenn Benutzer A eine Notiz erstellt und Benutzer B versucht, diese Notiz zu kommentieren, sendet oder simuliert tastypie eine POST-Anfrage, um diese Notiz zu bearbeiten. Dieser Versuch wird abgelehnt, da Benutzer B die Notiz nicht erstellt hat. Daher schlägt das Erstellen des Kommentars fehl.
Die Frage ist: Gibt es einen Weg zu beiden:
Vielen Dank im Voraus für alle Einsichten.
Bearbeiten:
Ich habe einen dicken fetten Hack, der das erreichen kann. Ich bin mir ziemlich sicher, dass es sicher ist, aber ich bin nicht positiv; Ich werde versuchen, einige Abfragen zu erstellen, um sicherzustellen, dass. Anstatt fields.ForeignKey
in Comment
für Note
zu verwenden, erstelle ich ein benutzerdefiniertes Feld:
Jedes Mal, wenn wir versuchen, diese verwandte Ressource zu erstellen, markieren wir die Anfrage als GET
(da wir erwarten, dass sie mit einer SELECT
-Abfrage übereinstimmt und nicht mit UPDATE
, die mit PUT
oder% übereinstimmt Code%). Das ist wirklich hässlich und möglicherweise unsicher, wenn es falsch verwendet wird, und ich hoffe auf eine bessere Lösung.
Edit 2: Nach dem Lesen der tastypie-Quelle gibt es, soweit ich das beurteilen kann, keine Möglichkeit, die Autorisierung durch die Abfrage zu filtern, die tatsächlich gesendet wird.
Wie auf der Diskussion Ссылка :
Die Methode, die bestimmt, ob ein Resource
aktualisiert werden kann, ist can_update
. Daher müssen Sie eine Unterklasse von NoteResource
:
Lassen Sie dann CommentResource
standardmäßig auf Notizen verweisen: note = fields.ForeignKey(SafeNoteResource, 'note')
.
Eine einfache Lösung sollte darin bestehen, in apply_limits
nachzusehen, ob die Anfrage für eine Note Ressource oder eine Kommentar Ressource ist. z.B. etwas wie
Dann beschränken Sie den Zugriff auf Notes nur für denselben Benutzer, wenn der Benutzer direkt auf eine Note Ressource zugreift und nicht über andere verwandte Ressourcen wie Kommentare .
update: oder eine etwas sicherere Option wäre, zu überprüfen, ob die Anfrage nicht mit 'api / v1 / comment' beginnt - also geben Sie nur den Kommentarzugriff und nicht alles anders als Notiz. Es gilt jedoch das gleiche Prinzip. Seien Sie vorsichtig mit diesem textbasierten Vergleich des Anfragepfads, um Fälle zu vermeiden, in denen jemand einfach eine Zeichenfolge an Ihre URL anhängt / vorpert, um Ihre Autorisierung zu umgehen. Hoffentlich ist das Voranstellen begrenzter, da es die richtige URL in urls.py treffen muss, weshalb ich startswith
hier verwendet habe. Natürlich müssten Sie die Pfadzeichenfolge anpassen, damit sie mit Ihren typischen URLs übereinstimmt.