PHP Rechtesystem

darton

Lt. Junior Grade
Registriert
Okt. 2004
Beiträge
282
Hallo!
Ich brauche für eine Homepage, die ich momentan programmiere, ein System, mit dem ich Benutzer für vier unterschiedliche Bereiche die Zugriffe read/update/delete gewähren kann. Die Rechte eines Nutzers könnten dann beispielsweise so aussehen:
Code:
            read     update     delete
Bereich 1     x        x           x
Bereich 2     x        x
Bereich 3     x
Bereich 4     x
Eine solche Rechtezuweisung müsste dann für jeden Benutzer existieren. Jetzt ist zunächst die Frage, wie ich das in einer Datenbank unterbringe. Also ich habe ja eine Tabelle mit allen Usern inkl. Username, Passwort, ID usw. und eine Tabelle mit den Rechten, wo ich dann eine Spalte für die Userid habe, eine für den Bereich und eine für das Zugriffsrecht. Ein Datensatz wäre dann z.B. 1|1|1, was bedeutet, dass der Benutzer mit der ID 1 Read-Zugriffe auf den Bereich 1 hat. Also read/update/delete haben dann die Nummern 1/2/3. Was nur ein bisschen blöd ist, ist dass man nicht sehr flexibel gegenüber Änderungen an den Rechten oder den Bereichen ist. Wenn ich z.B. einen Bereich 5 erstellen würde, müsste ich erstmal jedem Benutzer das Zugriffsrecht 'read' hinzufügen. Aber ich glaube, sowas kann man kaum automatisieren. Wäre denn eine solche Datenstruktur sinnvoll?

(Nur zur Info, fall es irgendwas verändert: Es werden wahrscheinlich nie mehr als 10 Benutzer erstellt werden.)
 
Wenn eh jeder lesen kann, dann brauchst du es auch nicht angeben.

Ansonsten machst du einfach eine Funktion, die abfragt welche rechte gesetzt werden sollen. angenommen du erstellst einen nutzer und willst ihm für eine kategorie rechte geben. dann bekommt die funktion die kategorie, und meinetwegen booleans für die einzelnen typen der rechte mit. dann machst du in der funktion eine abfrage welche rechte auf true stehen. und je nach dem welche ausgewählt sind, wählst du ein sql querry aus, welches dann einen benutzer anlegt und dafür in der tabelle kategorie die entsprechenden rechte anlegt.
 
Zuletzt bearbeitet:
Ja ok, war auch nur ein Beispiel. Man müsste auf jeden Fall die Rechte aller betroffenen User ändern.
 
In der Regel ist sowas ja nicht Benutzerbasiert sondern Rollenbasiert.

DB Tabellen - Rolle
id, rollenname, description

DB Tabelle - Benutzer
id, name,pw,..., rollenId(foreignKey)

DB Tabelle - Bereich/Webseite
id, bereich,..

DB Tabelle - Access
id, rollenId(foreignKey), bereichId(foreignKey), read, update, delete

Alternative kann man die Einzelenen Rechte (read,update,delete) auch nochaml in eine extra Tabelle auslagern.

Wenn du es wirklich Nutzerbasiert willst kannst die Rolle einfach weg lassen. Eine detailiertere Beschreibung wirst von mir nicht bekommen, da es sich vermutlich um eine Hausaufgabe oder ähnliches handelt.
 
Hehe, nee es ist keine Hausaufgabe.
Dann habe ich aber noch eine zweite Frage. Um das Rechtesystem nun anzuwenden, muss ich doch jede Ressource, die ich schütze möchte, sei es nun eine ganze Seite oder auch nur ein Button in der View, in eine If-Abfrage einschließen, die überprüft, ob der Nutzer die entsprechenden Rechte hat, oder? Die Informationen dazu würden dann aus der Session kommen, in der gespeichert wird, welche Rechte der Nutzer momentan hat.
 
Das hängt von deinen Anforderungen ab. Bei größeren Projekten mit entsprechendem Rechtesystem geht man häufig jedesmal direkt auf die Datenbank (wobei sicherlich auch gecacht wird). Für dein Vorhaben wäre das mit der Session auch in Ordnung, wenn auch unflexibler.

Mit der If-Abfrage hast du recht. Meistens kapselt man das aber, dann schrumpft die Abfrage auf "if(user.isInRole(rolename))".
 
Zuletzt bearbeitet:
Wobei if(user.isInRole(rolename)) glaube ich nicht die richtige Abfrage ist. Man müsste eher die Frage if (user.hasRights(bereich, right)) stellen. Wenn man nämlich eine Rolle hinzufügt, der Zugriff auf diesen Bereich haben soll, müsste man ja den Quellcode verändern. Wenn im Quellcode aber steht if (user.hasRights(bereich, right)), dann müsste man nur die Datenbank verändern.
 
Kannst du denn deine Berechtigungen denn gar nicht in Rollen gliedern? Rolle X darf in Bereich 4 dies und das, Rolle Y darf in Bereich 5 dies und jenes, wobei jeder Rolle immer mehrere Leute angehören.

Wenn du wirklich für jeden User fein granular alles einstellen möchtest, dann eignet sich Rollenorientierung hier vermutlich wirklich nicht so gut. Auch wenn du natürlich für jeden Bereich individuelle Rollen anlegen könntest, z.B. "Bereich5NewsLesen".

Ansonsten baust du dir halt eine Tabelle mit 5 Spalten, UserID, BereichID, r, u, d und kannst dann für jeden User individuell für jeden Bereich die Rechte abfragen. Ist aber auch nicht optimal, weil das eben genau nichts mehr mit Rollen zu tun hat. Wenn ein Admin z.B. in allen Bereichen alles tun darf, dann braucht jeder Admin schon mal ziemlich viele Einträge in der DB und du kannst im Code nicht mehr einfach abfragen "isInRole('Admin')". Oder du kombinierst beide Wege über ein logisches oder, also semantisch user.hasRights(bereich, right) OR user.isInRole('Moderator')
 
Zuletzt bearbeitet:
Doch klar, ich möchte es ja in Rollen aufteilen. Aber dann sähe die Abfrage ja immer so aus:
Code:
if (user.isInRole('Moderator') || user.isInRole('Administrator'))
Und je mehr Rollen ich habe, desto länger würde dann das Statement werden. Vor allen Dingen müsste ich es immer im Quellcode ändern.
Wenn ich es so mache,
Code:
if (user.hasRights(bereich, right))
dann reicht es, wenn man in der hasRights Methode herausfindet, in welcher Rolle der User ist und welche Aktionen er dadurch ausführen darf. Finde das besser als ersteres.
 
Das Statement ließe sich natürlich verkürzen indem du deine Rollen hierarchisch aufbaust:
Also fängst du beim Gast an: User erbt von Gast, Mod erbt von User, Admin erbt von Mod
Dann kannst du einfach auf die Klassenhierarchie setzen und schreibst z.B.
if(user.isInRole('Mod')), dann würde das auch automatisch für alle Admins gelten, da diese Teil der Klasse Mod sind.

Das ganze ist sehr einfach und praktikabel für streng hierarchische Systeme, aber wird dann unübersichtlich/kompliziert/unmöglich, wenn du Sonderfälle hast, wie z.B. User1 ist ein Moderator, aber darf zusätzlich diese Kleinigkeit aus dem Admin-Bereich benutzen...

Überlegs dir gut :)
 
Zurück
Oben