Ein einfaches, flexibles Rechtesystem, Version 5

Alte Version

Dies ist eine alte Version des Inhalts in unserem Archiv. Besuchen Sie die aktuelle Version dieser Seite.

Diese Version wurde von Cooney3000 am 24. May 2019 um 01:37 Uhr erstellt.
Bemerkung des Bearbeiters: Funktion mit alternativer Logik hinzugefügt

Änderungen gegenüber vorheriger Version anzeigen


In nahezu allen Situationen, in denen mehr als ein Benutzer auf eine dynamische Webapplikation - wie zum Beispiel ein kleines CMS - zugreifen können soll, ist es von nöten sich mit einem Benutzerrechtsystem auseinanderzusetzen. Um diese Problemstellung anzugreifen, gibt es verschiedene Möglichkeiten. Hier möchte ich eine Methode vorstellen, in der das Binärsystem zur Lösung dieser Problematik verwendet wird. Diese Technik mag auf den ersten Blick sehr abstrakt und undurchsichtig erscheinen, ist jedoch in der Praxis sehr flexibel und einfach einzusetzen.

Mathematische Grundlagen und Prinzip des Systems

Das System soll auf dem Binärsystem basieren. Konkret heißt dies, dass verschiedene Potenzen der Zahl 2 eingesetzt werden. Hierbei steht jede Potenz für ein Recht, was dem Benutzer eingeräumt werden kann. Dies könnte so wie in der folgenden Tabelle dargestellt werden:

Recht
Zweierpotenz
dezimaler Wert
Eintrag auf der Startseite verfassen
20
1
Gästebucheinträge löschen
21
2
Downloads hinzufügen
22
4
Fotos in der Bildergalerie freischalten
23
8
...
2X

Wie die Tabelle erkennen lässt, hat jedes Recht für den Benutzer seinen eigenen Zahlenwert, der einer Potenz der Zahl 2 entspricht.

In der Regel ist es jedoch nicht so, dass ein einzelnen Recht pro Benutzer ausreicht. Es muss also eine Möglichkeit gefunden werden, dass mehrere Rechte miteinander verknüpft werden können. Dies kann über die Addition erreicht werden. Die Summe der einzelnen Rechte ergibt also die Gesamtrechte eines Benutzers. Ein Beispiel zur Veranschaulichung:

Benutzer A soll Einträge auf der Startseite verfassen und Downloads hinzufügen können. Die Summe seiner Rechte ist also 1 + 4 = 5. Benutzer B jedoch Gästebucheinträge freischalten und Downloads hinzufügen. Hier ergibt sich ein Gesamtrecht von 6. Dies könnte beispielsweise in einer Datenbank eingetragen werden.

Betrachtet man diese Werte ein wenig genauer, so fällt auf, dass es dank dieses Systems möglich ist, dass eindeutige Werte zu erzeugen. Nehmen wir das Beispiel der Zahl 4: Selbst wenn alle Rechte, deren Werte kleiner als 4 sind - hier 1 und 2 - addieren, erreichen wir nur 1 + 2, also 3. Übertragen wir dies nun auf den Wert 8, so erhalten wir die Summe 1 + 2 + 4 = 7. Somit ist gewährleistet, dass die Gesamtrechte eindeutig unterscheidbar sind, also keine Fehler auftreten durch das Aufsummieren auftreten können. Dies ist von großer Bedeutung für unser System.

Umsetzung in PHP

Nun bleibt an sich nur noch die Frage zu klären, wie die Gesamtrechte, die ja gespeichert werden sollen, wieder in ihre einzelnen Komponenten zerteilt werden können, so dass eine Überprüfung durchgeführt werden kann. Hier soll uns eine Funktion unter die Arme greifen, die wie folgt aussieht:

 
PHP
1
2
function pruefung($benutzerrechte, $benoetigt) {
}

Unserer Funktion übergeben wir 2 Parameter:

  1. Die Gesamtbenutzerrechte des Benutzers (aus der Datenbank)
  2. Die Rechte, die benötigt werden um die Seite aufzurufen

Anschließend sorgen wir dafür, dass die Gesamtrechte wieder in ihre einzelnen Komponenten zerlegt werden, welche wir in einem Array ablegen, das jedoch zunächst initialisiert wird.. Dazu wenden wir eine Schleife an:

 
PHP
1
2
3
$rechte = array();
for($i = 3; $i >= 0; $i--) {
}

Tipp: Man könnte hier auch einfach eine Zahl, die größer als der maximale Exponent ist, einsetzen. So wäre man flexibler und müsste bei der Einführung von neuen Rechten die Funktion nichts ändern. Der zusätzliche Rechenaufwand für den Server ist hierbei relativ gering.

Der Startwert der Schleife ist hierbei der höchste Exponent, dem wir ein Recht zugeordnet haben. In meinem Beispiel ist das die Zahl 3 (vergleiche mit der Tabelle oben).

Nun beginnen wir mit dem Zerlegen der Summe für die Gesamtrechte. Dazu lassen wir pro Schleifendurchgang die Potenz zur Basis 2 von der Variablen $i berechnen. Dies übernimmt die Funktion pow().

 
PHP
1
$wert = pow(2, $i);

Diese Zahl vergleichen wir nun mit unseren Gesamtrechten. Wie wir oben festgestellt haben, kann der Benutzer nur Rechte für diese Seite haben, wenn seine Benutzerrechte mindestens genausogroß sind wie der Wert, den wir mit pow() berechnet haben:

 
PHP
1
2
if($benutzerrechte >= $wert) {
}

Trifft diese Kontrollstruktur zu, ist also klar, dass der Benutzer dieses Recht inne hat. Wir fügen dies nun dem $rechte Array hinzu und ziehen den Wert von seinen Gesamtrechten ab, so dass dieser Wert beim nächsten Durchlauf der Schleife keinen Fehler verursacht.

 
PHP
1
2
$rechte[] = $wert;
$benutzerrechte -= $wert;

Ist die Schleife durchgelaufen, können wir endlich prüfen, ob der Benutzer das geforderte Recht inne hat oder nicht. Da wir ein Array durchsuchen müssen, verwenden wir die Funktion in_array() und erzeugen je nach Erfolg einen Rückgabewert.

 
PHP
1
2
3
4
5
6
if(in_array($benoetigt, $rechte)) {
    return true;
}
else {
    return false;
}

Zum Abschluß noch einmal die vollständige Funktion im Überblick:

 
PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php
    function pruefung($benutzerrechte, $benoetigt) {
    $rechte = array();
        for($i = 3; $i >= 0; $i--) {
            $wert = pow(2, $i);
            if($benutzerrechte >= $wert) {
                $rechte[] = $wert;
                $benutzerrechte -= $wert;
            }
        }
        if(in_array($benoetigt, $rechte)) {
            return true;
        }
        else {
            return false;
        }
    }
?>

Zurück zu unseren Benutzern A und B (siehe oben). Nehmen wir einmal an Benutzer A versucht auf die Seite zuzugreifen, die es ihm erlaubt Einträge auf der Startseite zu verfassen. Hier würde die Überprüfung wie folgt aussehen:

 
PHP
1
2
3
4
5
6
if(pruefung(5, 1)) {
    // Formular
}
else {
    die("Zugriff verweigert");
}

Siehe da: Benutzer A erhält Zugriff. Setzt man jedoch statt der 5 den Wert 6 von Benutzer B ein, wird der Zugriff verweigert. Das System funktioniert also.

Vor- und Nachteile

Vorteile

  • Das System ist einfach erweiterbar, indem einfach weitere Potenzen hinzugefügt werden. Gegebenenfalls muss nur die Funktion zur Überprüfung angepasst werden.
  • Die Anzahl der möglichen Rechte ist nach oben hin theoretisch offen.
  • Bei Einführung neuer Rechte muss die Datenbankstruktur nicht geändert werden.

Nachteile

  • Für das menschliche Auge ist bei Betrachtung der Gesamtrechte nicht sofort erkennbar, ob ein Benutzer für einen bestimmten Bereich die entsprechenden Rechte hat oder nicht.

Alternative:

Die Funktion mit der völlig gleichen Wirkung in nur einer Zeile, ohne array, Schleife, if etc.:

 
HTML
1
2
3
4
5
<?php 
    function pruefung($benutzerrechte, $benoetigt) {
        return $benoetigt == ($benutzerrechte & $benoetigt); 
    }
?>