• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Interner Bereich & Login Klasse

T!P-TOP

Mitglied
Ich hätte da mal ein paar Fragen.

1) Ist der Weg, wie ich den Internen Bereich sichere in Ordnung? Ich hab bei diesem Projekt nur eine index.php, der rest sind Klassen.

index.php:
PHP:
<?php
session_start();
include("inc/includeAllClasses.php");

if($_SESSION['user']['login'] == false)
{
    HTML::printHead();
    echo '<link rel="stylesheet" type="text/css" href="startseite.css">';
    HTML::prinBody();
    $login = new login();
    $login->printLoginForm();

    if(isset($_POST['doLogin']))
    {
        if($login->checkLoginData)
        {
            $_SESSION['user']['login'] = true;
            header("Location: index.php"); //Die seite einfach neu laden
        }
        else
        {
            echo 'Fehler'
        }
    }
    
    HTML::printFoot();
}
else
{
    HTML::printHead();
    echo '<link rel="stylesheet" type="text/css" href="internes.css">';
    HTML::prinBody();
    //ander Objekte erstellen, Inhalt für den internen Bereich laden
    HTML::printFoot();
}
?>
In der index.php wird einfach überprüft, ob $_SESSION['user']['login'] true ist, falls ja, wird dem eingeloggten User der Inhalt angezeigt, ansonsten wird eine Methode namen printLoginForm ausgerufen, die, wie der Name schon sagt, ein Login Formular ausgibt.

Wie sollte man bei einem größeren Projekte diesen Abschnitt lösen? Ist das so In Ordnung wie ich es gestalte? Oder sollte ich bei einem erfolgreichen Login nicht auf die index.php, sondern auf eine andere Page den eingeloggten User schicken, zb. intern.php oder was auch immer?

Nun noch eine 2. Frage:


Die Login Klasse sieht so aus:
PHP:
<?php
class Login 
{
    public function printLoginForm()
    {
        echo '<form action="" method="post" />';
        echo '<input type="text" name="username" />';
        echo '<input type="password" name="password" />';
        echo '<input type="submit" name="doLogin" />';
        echo '</form>';
    }
    
    public function checkLoginData($username, $password)
    {
        if($username == "" OR $password == "")
        {
            return false;
        }
        else
        {
            $sql = MySQL::query("SELECT `id`, `username`, `password` FROM `users` WHERE `username` = '".mysql_real_escape_string($username)."'");
            if(mysql_num_rows($sql) == 0)
            {
                //des Username existiert nich
                return false;
            }
            else
            {
                $row = mysql_fetch_object($sql);
                if($row->password == $password)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    
    }

}
?>
Wie man sehen kann überprüfe ich verschiedene Dinge:
- wurde ein Feld freigelassen
- gibts es den Usernamen überhaupt
- ist die Kombination aus password und username nicht korrekt

Trifft eines dieser Dinge zu, gebe ich einfach mit return false zurück, trifft keines dieser Dinge zu, gebe ich true zurück. In der Index.php überprüfe ich nun, ob die Methode true oder false zurückgibt. Das ganze funktioniert auch alles - nur weiß ich nicht, wieso die Methode false zurück gibt, da ich ja nicht den Grund für das false mitsende. Das false kann durch eine der 3 oben genannten Dinge auftreten -das ist mir aber zu ungenau. Ich will mit dem return zum Einen false bzw true zurück geben, zum Anderen auch noch die Fehlermeldung. Wie löse ich das am besten?

Bei einem True will ich noch die User ID, die ich mit dem Query abfrage an die index.php übermitteln, da ich diese im internen Bereich benötige, um den User bei späteren Aktionen zu identifizieren.

Nochmal kurz zusammengefasst:
Tritt ein Fehler auf, will ich false und die dazu gehörende Fehlermeldung zurück geben. Tritt kein Fehler auf, will ich ein true und die User ID übermitteln.

Wäre euch sehr dankbar, für gute Lösungsansätze! :-)

Grüße
 
Ist der Weg, wie ich den Internen Bereich sichere in Ordnung?

Du meinst, ob er sicher ist? Ja, sieht auf den ersten Blick gut aus. Beim Aufruf von checkLoginData in index.php fehlen Parameter.

Du hast allerdings das Problem, nicht zu wissen, *welcher* Benutzer sich mit dieser Session eingeloggt hat. Schreib lieber die user_id in die Session. Als eingeloggt gilt dann jede Session mit user_id > 0.

Wie sollte man bei einem größeren Projekte diesen Abschnitt lösen? […] Oder sollte ich bei einem erfolgreichen Login nicht auf die index.php, sondern auf eine andere Page den eingeloggten User schicken, zb. intern.php oder was auch immer?

Auf welchen Pfad du den Nutzer nach dem Login schickst, ist weniger eine grundsätzliche Frage guten Designs, sondern mehr der jeweiligen Vorlieben/Anforderungen. Ist dir überlassen.

Die Prüfung, ob ein Besucher eingeloggt ist, kann so eingebunden werden, dass sie bei jedem Request zu Beginn automatisch ausgeführt wird. Etwa in Form einer Funktion/Methode getLoggedInUser, die anhand der user_id in der Session entweder die Daten des eingeloggten Users (eine Instanz eines User-Objekts oder so) zurückgibt oder null.

Im folgenden Code kannst du dann Abfragen machen wie: if ($user !== null) { /* Eingeloggt */ }.

Dazu bieten sich FrontController-Designs an, also ein Webseitenaufbau, der jeden Request über index.php abfertigt. Siehe dazu auch unlängst diese beiden Threads:

- http://www.html.de/server-apache-co/37413-rewrite-2-fragen.html
- http://www.html.de/php/37379-php-datei-includen-aber-nicht-ausgeben.html#post274394

Für Frage 2 fange ich nachher einen neuen Post an, falls mir niemand zuvorkommt. ;)
 
Du hast allerdings das Problem, nicht zu wissen, *welcher* Benutzer sich mit dieser Session eingeloggt hat. Schreib lieber die user_id in die Session. Als eingeloggt gilt dann jede Session mit user_id > 0.
Du meinst, die user_id in dem $_SESSION Array reinschreiben? Falls du das meinst, das habe ich auch vor - nur da ist eben meine 2. Frage - wie kann ich die User Id, die ich in der checkLoginData() Methode abgefragt habe, an die index.php übermitteln und auch noch den booleschen Wert true - 2 werte mit einem return...

Die äußerte if Bedingung soll also nicht mehr checken, ob $_SESSION['user']['login'] true ist, sondern ob $_SESSION['user']['id'] größer als 0 ist!? Habe ich das richtig verstanden?


Aber ich habe da bereits ne Idee wie ich das mit den return hinbekomme.

Ich habe mir den Inhalt deiner beiden Links mal grob angesehen. Allerdings sehe ich jetzt nicht den Zusammenhang?



Ob ein User eingeloggt ist oder nicht prüfe ich in der index.php.
Ich habe noch eine weiter Klasse namens "Content", die generiert den Inhalt und fügt diesen anschließend in der index.php in folgenden Teil ein:

PHP:
<?php
session_start();
include("inc/includeAllClasses.php");

if($_SESSION['user']['login'] == false)
{
    //Logoinformular etc.
}
else
{
    HTML::printHead();
    echo '<link rel="stylesheet" type="text/css" href="internes.css">';
    HTML::prinBody();
    
    //CONTENT BEGIN
    $content = new Content($_GET['navi']);
    $content->printContent();
    //CONTENT END

    HTML::printFoot();
}
?>
Ich habe wie gesagt nur die index.php. Über parameter Urls in der navi tausch ich den Inhalt in der index.php aus. Klickt einer auf den Link www.domain.de/index.php?navi=startseite wird der Wert von navi, in dem Fall "startseite" an das Objekt "Content" übergeben, sofern die äußerste if Bedingung (=
if($_SESSION['user']['login'] == false){ //...}else{...} ) eine Session erkennt. Wenn nicht, wird halt nur das Login Formular ausgegeben.

Ist das soweit In Odrnung?

Mit Entwurfsmustern habe ich mich noch nicht beschäftigt und habe es erstmal auch nicht vor, da das dann schon ne höhere Liga ist.

Grüße
 
Du meinst, die user_id in dem $_SESSION Array reinschreiben?

Ja, genau.

Mit den beiden Links wollte ich andeuten, wie man Seiten so anlegt, dass sie über eine einzige index.php laufen und wie dann die URLs dennoch über mod_rewrite so umgeschrieben werden können, dass sie einer Verzeichnisstruktur gleichen.

sondern ob $_SESSION['user']['id'] größer als 0 ist!? Habe ich das richtig verstanden?

Dann könntest du dir die zusätzliche ['user']['login']-Variable sparen. Aber im Prinzip geht es auch mit der. Mir ging es hauptsächlich darum, zu empfehlen, die User-ID auch mit in der Session abzulegen, um den Nutzer tatsächlich identifizieren zu können.

Ich habe wie gesagt nur die index.php. Über parameter Urls in der navi tausch ich den Inhalt in der index.php aus. Klickt einer auf den Link www.domain.de/index.php?navi=startseite wird der Wert von navi, in dem Fall "startseite" an das Objekt "Content" übergeben

Das klingt gut.

Ich will mit dem return zum Einen false bzw true zurück geben, zum Anderen auch noch die Fehlermeldung. Wie löse ich das am besten?

Bei einem True will ich noch die User ID, die ich mit dem Query abfrage an die index.php übermitteln, da ich diese im internen Bereich benötige, um den User bei späteren Aktionen zu identifizieren.

Ich gebe dir mal einen eher pragmatischen Hinweis, wie du das machen kannst. Es gäbe andere Möglichkeiten, aber da müsste man schon etwas weiter ausholen.

(Der Code ist so nicht ausführbar – klar.)

PHP:
<?php

class TestDummy
{
    /**
     * Loggt einen Nutzer ein
     * 
     * @param string $username
     * @param string $password
     * @param array $errors Füllt das Array mit Fehlermeldungen
     * @return int Gibt die ID des eingeloggten Nutzers zurück oder 0 bei Fehler 
     */
    public function loginUser($username, $password, array &$errors)
    {
        $returnValue = 0;

        if($username == "" OR $password == "")
        {
            $errors[] = 'Nutzername oder Passwort leer';
        }
        else
        {
            $sql = MySQL::query("
                SELECT
                        `id`, `username`, `password`
                FROM
                        `users`
                WHERE
                        `username` =
                                '" . mysql_real_escape_string($username) . "'
                ");

            if(mysql_num_rows($sql) == 0)
            {
                $errors[] = 'Nutzername existiert nicht';
            }
            else
            {
                $row = mysql_fetch_object($sql);
                if($row->password == $password)
                {
                    $returnValue = $row->id;
                }
            }
        }

        return $returnValue;
    }
}

$errors = array();
$userId = loginUser($username, $password, $errors);

if ($userId === 0) {
    foreach ($errors as $error) {
        echo '<p>' . $error . '</p>';
    }
} else {
    echo '<p>Logged in with id ' . $userId . '</p>';
}
 
Zurück
Oben