Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Datenbankschema für ACL

Meiner Erfahrung nach besteht die eigentliche Frage hauptsächlich darin, ob es zu einer benutzerspezifischen Zugriffsbeschränkung kommen wird oder nicht.

Angenommen, Sie entwerfen beispielsweise das Schema einer Community und erlauben Benutzern, die Sichtbarkeit ihres Profils umzuschalten.

Eine Option besteht darin, an einem öffentlichen/privaten Profil-Flag festzuhalten und sich an umfassende, vorbeugende Berechtigungsprüfungen zu halten:„users.view“ (zeigt öffentliche Benutzer an) vs. sagen wir „users.view_all“ (zeigt alle Benutzer an, für Moderatoren) .

Eine andere beinhaltet verfeinerte Berechtigungen, Sie möchten vielleicht, dass sie in der Lage sind, Dinge so zu konfigurieren, dass sie sich (a) für alle sichtbar machen können, (b) für ihre handverlesenen Freunde sichtbar sind, (c) vollständig privat bleiben und vielleicht (d ) für alle sichtbar, außer für ihre handverlesenen Trottel. In diesem Fall müssen Sie besitzer-/zugriffsbezogene Daten für einzelne Zeilen speichern, und Sie müssen einige dieser Dinge stark abstrahieren, um zu vermeiden, dass die transitive Schließung eines dichten, orientierten Diagramms zustande kommt.

Bei beiden Ansätzen habe ich festgestellt, dass die zusätzliche Komplexität bei der Bearbeitung/Zuweisung von Rollen durch die daraus resultierende Leichtigkeit/Flexibilität bei der Zuweisung ausgeglichen wird Berechtigungen für einzelne Daten und dass Folgendes am besten funktioniert:

  1. Benutzer können mehrere Rollen haben
  2. Rollen und Berechtigungen werden in derselben Tabelle mit einem Flag zusammengeführt, um die beiden zu unterscheiden (nützlich beim Bearbeiten von Rollen/Berechtigungen)
  3. Rollen können andere Rollen zuweisen, und Rollen und Perms können Berechtigungen zuweisen (aber Berechtigungen können keine Rollen zuweisen) aus derselben Tabelle heraus.

Der resultierende orientierte Graph kann dann in zwei Abfragen gezogen werden, ein für alle Mal in angemessener Zeit mit der von Ihnen verwendeten Sprache erstellt und für die spätere Verwendung in Memcache oder ähnlichem zwischengespeichert werden.

Von dort aus müssen die Berechtigungen eines Benutzers abgerufen werden, indem überprüft wird, welche Rollen er hat, und sie mithilfe des Berechtigungsdiagramms verarbeitet werden, um die endgültigen Berechtigungen zu erhalten. Überprüfen Sie die Berechtigungen, indem Sie überprüfen, ob ein Benutzer die angegebene Rolle/Berechtigung hat oder nicht. Führen Sie dann Ihre Abfrage aus/geben Sie basierend auf dieser Berechtigungsprüfung einen Fehler aus.

Sie können die Prüfung für einzelne Knoten erweitern (z. B. check_perms($user, 'users.edit', $node) für "kann diesen Knoten bearbeiten" vs check_perms($user, 'users.edit') für "kann einen Knoten bearbeiten"), wenn Sie es brauchen, und Sie haben etwas sehr Flexibles/Einfaches für Endbenutzer.

Wie das Eröffnungsbeispiel veranschaulichen sollte, sollten Sie sich davor hüten, zu sehr auf Berechtigungen auf Zeilenebene zu setzen. Der Leistungsengpass liegt weniger beim Überprüfen der Berechtigungen eines einzelnen Knotens als beim Abrufen einer Liste gültiger Knoten (d. h. nur derjenigen, die der Benutzer anzeigen oder bearbeiten kann). Ich würde von allem abraten, das über Flags und user_id-Felder innerhalb der Zeilen selbst hinausgeht, wenn Sie sich nicht (sehr) mit Abfrageoptimierung auskennen.