[PHP][Source] Login-System mit Rechten

    • Release
    • Open Source

    Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von Umbekannt.

      [PHP][Source] Login-System mit Rechten

      Hallo Community,

      da mir die lezten Tage ziemlich fad, dachte ich ich mach mal was für die allgemeinheit,
      hier ein sourecode eines login-systems mit rechte-abfrage.

      Es ist einfach nur ein Sourcecode, der zum weitermachen animieren soll.

      Code darf nach einem Beitrag zu diesem Thema frei verwendet werden!

      Falls ihr Sicherheitslücken findet, bitte ich euch diese Sofort hier bekannt zu geben, werde ich dann sofort ausbessern


      Vorschläge für besseren Code werde ich ebenfalls ausbessern



      Voraussetzungen:
      - Webserver mit MYSQL
      - Webserver mit PHP

      Quelle: Selbst programmiert



      Dateistruktur:
      - include
      - mysql_settings.php
      - class
      - class_users.php

      - login_erfolgreich.php
      - login.php
      - functions.php

      Login.php

      PHP-Quellcode

      1. <?php
      2. include ( "functions.php" );
      3. if ($_SERVER["REQUEST_METHOD"] == "POST")
      4. {
      5. if (login($_POST['txt_username'], $_POST['txt_password']))
      6. {
      7. header("location: login_erfolgreich.php");
      8. }
      9. else
      10. {
      11. echo "Login fehlgeschlagen (falscher Benutzername oder Passwort)";
      12. }
      13. }
      14. ?>
      15. <!DOCTYPE html>
      16. <html>
      17. <head>
      18. <meta charset="utf-8">
      19. <title>Demo: User/Rechte System</title>
      20. </head>
      21. <body>
      22. <form action="" method="POST">
      23. <input type="text" name="txt_username">
      24. <br />
      25. <input type="password" name="txt_password">
      26. <br />
      27. <input type="submit" value="login">
      28. </form>
      29. </body>
      30. </html>


      login_erfolgreich.php

      PHP-Quellcode

      1. <?php
      2. include ( "functions.php" );
      3. check_login();
      4. check_rights(array('1', '2', '3'));
      5. ?>
      6. <!DOCTYPE html>
      7. <html>
      8. <head>
      9. <meta charset="utf-8">
      10. <title>Demo: User/Rechte System</title>
      11. </head>
      12. <body>
      13. <h1> Du hast die nötigen Rechte um diese Seite zu besichtigen </h1>
      14. </body>
      15. </html>



      functions.php

      PHP-Quellcode

      1. <?php
      2. include( "class/class_users.php" );
      3. session_start();
      4. function login ($username, $password) {
      5. $myuser = new user;
      6. if ($myuser->_login($username, $password))
      7. {
      8. $_SESSION['user_object'] = $myuser;
      9. return true;
      10. }
      11. else
      12. {
      13. return false;
      14. }
      15. }
      16. function check_login () {
      17. if (!isset($_SESSION['user_object']))
      18. {
      19. zugriff_verweigern();
      20. }
      21. }
      22. function zugriff_verweigern() {
      23. echo "Zugriff verweigert";
      24. die;
      25. }
      26. function check_rights ($r) {
      27. if (isset($_SESSION['user_object']))
      28. {
      29. $flag = false;
      30. $user_right = $_SESSION['user_object']->getRights();
      31. foreach ($r as $rights)
      32. {
      33. if ($rights == $user_right)
      34. {
      35. $flag = true;
      36. }
      37. }
      38. if (!$flag)
      39. {
      40. zugriff_verweigern();
      41. }
      42. }
      43. else
      44. {
      45. zugriff_verweigern();
      46. }
      47. }
      48. ?>


      include/mysql_settings.php

      PHP-Quellcode

      1. <?php
      2. $db_host = "localhost";
      3. $db_user = "root";
      4. $db_pass = "";
      5. $db_name = "tsg";
      6. ?>



      class/class_users.php

      PHP-Quellcode

      1. <?php
      2. class user {
      3. private $id;
      4. private $username;
      5. private $password;
      6. private $user_rights;
      7. private $conn;
      8. public function __construct() {
      9. include ( "include/mysql_settings.php" );
      10. $this->conn = new mysqli($db_host, $db_user, $db_pass, $db_name);
      11. }
      12. private function _load ( $id ) {
      13. $query = "SELECT * FROM benutzer WHERE ID = '" . $id . "'";
      14. $result = $this->conn->query($query);
      15. if (!$result)
      16. {
      17. return false;
      18. }
      19. else
      20. {
      21. while ($row = $result->fetch_array())
      22. {
      23. $this->id = $id;
      24. $this->username = $row['username'];
      25. $this->password = $row['password'];
      26. $this->user_rights = $row['rights'];
      27. }
      28. return true;
      29. }
      30. }
      31. public function _login ($username, $password) {
      32. $u = mysqli_real_escape_string($this->conn, $username);
      33. $p = mysqli_real_escape_string($this->conn, sha1($password));
      34. $query = "SELECT * FROM benutzer WHERE username='" . $u . "' AND password = '" . $p . "'";
      35. $result = $this->conn->query($query);
      36. if (!$result)
      37. {
      38. return false;
      39. }
      40. else
      41. {
      42. if ($result->num_rows == 1)
      43. {
      44. while ($row = $result->fetch_array())
      45. {
      46. return $this->_load($row['ID']);
      47. }
      48. }
      49. else
      50. {
      51. return false;
      52. }
      53. }
      54. }
      55. public function getRights () {
      56. return $this->user_rights;
      57. }
      58. }
      59. ?>
      Wo ich gerade dieses Scripten hier sehe, möchte ich dir einige Tipps dazu auf den Weg bringen.
      In erster Linie php.net/manual/de/mysqli.prepare.php , außerdem gehören die Filterfunktionen in die Methoden, wo die Variablen
      dazu verwendet werden. D.h. auch ebenso entsprechend in die _load Methode. Letztlich muss der Sourcecode auf Wiederverwenbar sein,
      wenn man objektorientiert Programmieren möchte. Zu mal ich die Methodennamen in der Sicht besser beschreiben würde. "Load"? Ja load was?
      Die While Schleife in der Load Methode der User-Klasse kann ich nicht nachvollziehen. Du erwartest doch nur ein Ergebnis für eine entsprechende ID.
      Es wird niemals dazu kommen, dass du für eine ID sofern die Vergabe der IDs via AI erfolgt, doppelt vergeben ist.

      Daher kann man sih die kopfgesteuerte Schleife auch sparen.
      Aber auch generell würde ich die load Methode aufsplitten, in eine getBenutzer Methode und eine weitere setter für die Attribute (Wiederverwendbarkeit).

      Bzgl. der Rechteüberprüfung die Objekte in der Session zu hinterlegen find ich ja gar nicht mal so verkehrt, habe ich schon bei anderen Systemen
      wie der Online-Shop Software OXID Community/Professional und Enterprise gesehen.
      Aber das hat dort auch andere Hintergründe :)

      Was die Rechte betrifft finde ich gehören die nicht direkt an die User-Tabelle rangeklatscht als Spalte.
      Würde daraus eher mehrere Tabellen modelieren für das Rechtesystem um einfach wiederkehrende unnötige Redundanz zu vermeiden / Anomalien.
      Macht später bei größeren Tabellenschemen und wesentlich mehr Inhalten die Datenbank doch um einiges wartbarer, fällt aber auch
      mehr der CPU zu lasten, wegen ewigen joins und etc. Daher hätte ich lieber aus der Spalte für die Rechte nen Key-Value-Pair als Tabelle
      modeliert, zusätzlich dazu eine Koppeltabelle zwischen der KVP Tabelle und der Usertabelle.

      Zu mal auch irgendwie generell ein Datenbankschema von dir fehlt, womit hier sicherlich andere nicht so ganz nachvollziehen könnten, wie du dir das
      insbesondere mit dem Rechtesystem gedacht hast.

      Genauso wie die Functions.php hätte ich bei der Verwendung von Klassen auch als Klasse dargestellt. Nichts ist meiner Meinung nach schlimmer,
      als verschiedene Entwurfsmuster irgendwie ineinander zu flantschen. Wird zu viel Spaghetti Code.
      Genauso wenn man sich nach einem Schichtenmodel richtet, man Logik nicht in der Präsentationsschicht abbildet.

      Und zu guter letzt:
      php.net/basic-syntax.instruction-separation

      siehe Hinweis.

      Sonst ansich ein netter Ansatz und definitiv für einige hier in der Community hilfreich.

      Manawyrm schrieb:

      Online-Shop Software OXID


      OXID würde ich jetzt nicht als Parade-Beispiel für irgendetwas nehmen xD


      war das erste was mir dazu einfiel. Von OXID bin ich auch generell nicht all zu begeistert, insbesondere weils dazu keine Entwickler-Doku gibt für die EE Version, und man selbst als Partner mit unterschriebener NDA nichts brauchbares bekommt. Aber wie auch immer. Es war nur ein Beispiel.