Fragestellung zur Benutzerauthentifizierung / Login mittels MVC

Davicito

Erfahrenes Mitglied
Hallo an die Forum-Community,

ich hab da mal wieder eine Frage zum Thema MVC.

Nach einigen Recherchen und Video-Tutorials ist mir das MVC-Prinzip klarer geworden und würde dazu gerne ein kleines
Login-System bauen. Dabei möchte ich auch ebanfalls das HTML-Markup von der Programmlogik sauber trennen und mit Templates arbeiten wollen.
Dabei tun sich bei mir eine Frage auf, bei der ich trotz googeln nicht so richtig weiß, wie ich anfangen soll.

Ich habe mir folgendes Überlegt.
in der index.php möchte ich eine Instanz zu einem LoginController erstellen, die dann die Run-Methode aufrufen soll.
PHP:
<?php
require_once(config.php);

$controller = new LoginController();
$controller->run();

Der Controller selbst soll dann eigentlich zuerst das LoginTemplate aufrufen, um die Login-Informationen entgegen zu nehmen.
Anschließend sollen die Login-Eingaben, vom LoginController, weiter an das Model weiter gereicht werden um die Benutzereingaben zu Prüfen. Wenn alle Felder, vom Benutzer, korrekt ausgefüllt sind, soll das Model anschließend die Repository-Klasse
aufrufen um die Verbindung zur Datenbank herzustellen, um die Daten zu Prüfen.
Wenn der Benutzer in der Datenbank hinterlegt ist, wird eine Session im Model aufgebaut ect.

Soweit ist meine Überlegung.

Meine Frage stellt sich dabei, ob der Anfang so in Ordnung ist, dass ich über den LoginController, das LoginTemplate laden kann
oder ob ich das Login in der Index.php direkt realisieren kann, um so das MVC außen vor zu belassen.

Wie würdet Ihr da am besten vorgehen, habt Ihr schon mal solch ein Login mit MVC gebaut, geht das überhaupt oder bin ich dabei auf dem Holzweg? Ich brauch da mal einen Gedankenanschupser von Euch.

LG, Davicito.
 
Hallo,

ich selber würde keinen LoginController gestallten, sondern einen AuthController, über diesen du dann die komplette Zugriffsverwaltung abfrühstückst. Hast du dir mal bestehende Frameworks (CakePHP, Symfony2, Zend) wie die es lösen?

Gruß, Kalito
 
Hallo Kalito,

ich habe bereits damit begonnen einen Controller zu entwerfen, wo bei mich jetzt nur irritiert, dass ich zum Einen in dem Controller das LoginTemplate.php inkludieren muss und zum Anderen eine weitere Instanz aufrufen muss - zum Model - um den Login-Methode auszuführen, der die Benutzereingaben, durch den Controller, aus dem Template bekommen soll um sich mit dem DB-Server/Datenbank zu verbinden. Wenn ich dann die Login-Methode ausgeführt habe, kann ich das Ergebnis nicht zurückführen in den Controller. Es seiden, ich mach eine Login-Callback-Methode, der mir dann als Rückgabewert true oder false zurück liefert.

Hast Du da eine elegantere Lösung wie du es von der Überlegung her machen würdest?

Meine unfertige Test-Lösung:

index.php
PHP:
<?php 
require_once(config.php); 

$controller = new LoginController(); 
$controller->run();

Controller.php
PHP:
<?php
class LoginController
{
	public function run()
	{
		if(isset($_SESSION['bn_is_logged']) && !empty($SESSION['bn_is_logged']))
			echo 'Sie sind Eingelogt!';
		else{ 
			require_once("Templates".DIRECTORY_SEPARATOR."LoginTempl.php");
			$link = new LoginModel;
			$link->login($_POST['bn'], $_POST['pw'], $_POST['db']);
		}
	}	
}
?>

Model.php
PHP:
session_start();
	class LoginModel
	{
		public function login($bn, $pw, $db)
		{		
			try
			{
				$dbConnection = @new mysqli('localhost', $bn , $pw, $db);
				mysqli_set_charset($dbConnection, "UTF8");
				$_SESSION['bn'] = $bn;
				$_SESSION['bn_is_logged'] = true;
				return true;
			}
			catch(Exception $e)
			{
				echo'Fehler bei der Verbindung zur DB! -> '.$e;
			}
		}
		
		public function logout()
		{
			unset($_SESSION);
			session_destroy();
			return;
		}
}

LoginTemplate.php
PHP:
<!DOCTYPE HTML>  <!-- benötigt der IE -->
<html>
	<head>
		<title>Anmeldung</title>
		<link rel="stylesheet" type="text/css" href="style/style.css"> 
	</head>
	<body>	           
        <?php
		if(isset($_SESSION['bn_is_logged']) && $_SESSION['bn_is_logged'] == true)
			echo 'Du bist eingelogt '.$_SESSION['bn'];
			
		echo'<form class="LogContent" action="" method="post">'; 
			echo'Benutzername:<br>';
			echo'<input type="text" placeholder = "Benutzername" size="24" maxlength="50" name="bn"><br>';			
			echo'Passwort:<br>';
			echo'<input type="password" placeholder = "Benutzerpasswort" size="24" maxlength="50" name="pw"><br><br>';
			echo'Standort:';
			echo'<select size="1" maxlength="20" name="db">';
				echo'<option>   </option>';
				echo'<option>berlin</option>';
			echo'</select><br><br>';
			echo'<input type="submit" name="sumit" value="Login">';
		echo'</form>';			
	?>
	<form action="" methode="post">
		<input type="submit" name="logout" value="Logout">
	</form>
	</body>
</html>

Nicht vergessen ich mache gerade die ersten Gehversuche und sicherlich sind vielerlei Sicherheitslücken drinn und der Code ist noch eher nicht brauchbar. Ich wollt nur wissen ob Ihr/Du das von der Struktur her ähnlich so machen würdet.

Bei Frameworks hat man mir CakePHP geraten, da der Einstieg für PHP-Framework-Anfänger leichter ist als zB. bei Zend. Ich mache aber zur Zeit bewusst einen Bogen um die Framework-Geschichten, weil ich von Grund auf an, das Verständnis für das MVC-Konzept erlernen will, um zu verstehen wie die Frameworks Ticken. Ich mach das gerne Step by Step ^^.
So finde ich es auch nicht schlecht.
 
Also der Code sieht gruselig aus, vorallem scheint es bedenklich, dass datenbankname, passwort und benutzername aus dem POST-array, ergo vom User kommen...
 
Wieso eigentlich nicht?

Der User logt sich über einen Login-Template ein und drückt auf login! Somit werden die Daten an den DB-Server übermittelt und prüft, ob der Benutzer in der globalen Datenbank "Mysql" angelegt wurde und wenn kein Fehler zurückgeliefert wird, wurde die Verbindung erfolgreich aufgebaut.
Jedenfalls funktioniert es prima... Das man aus Sicherheitsgründen keine unmaskierten POST-Variablen nehmen soll, ist verständlich und werden nur aus diesem Grunde, später ersetzt. Vielmehr will ich versuchen das MVC Pattern Design zu verstehen und überspringe erstmal alle Feinheiten.

Also der Code sieht gruselig aus,

Was genau ist gruselig? Bitte näher erläutern!

Weitere Anregungen sind gerne erwünscht. Ich freue mich auch über Erfahrungen, Tipps wie Ihr die Struktur aufbaut... Und Bitte Ohne Frameworks. Ich kann das langsam nicht mehr hören! Ich will das Rad nicht neu erfinden. Es dient mir nur zum Verständnis!

LG, Davicito.
 
Zuletzt bearbeitet:
Mir ist folgendes aufgefallen

Im LoginController und LoginModel gibst du jeweils Text aus. Das solltest du bei einer klaren Strukturierung vermeiden.
Für das Rendern ist die View verantwortlich. Die View wird vom Controller instaziiert und mit Variablen gefüllt (aus DB oÄ.).

Ob die $_POST-Daten überhaupt abgeschickt worden sind, überprüfst du auch nicht.

In LoginModel::login() solltest du nicht die generische Exception abfangen, sodern direkt die Exception, die MySQLi wirft. Allerdings wirft der Konstruktur überhaupt keine Exception! Siehe Dokumentation: http://php.net/mysqli_set_charset


PS: Wieso sollte <!doctype html> vom IE gefordert sein? Das ist der Standard-Doctype, welcher heute genutzt warden sollte.
 
Vielen lieben Dank, ComFreek!

ich werde mir mal das Exception-Handling genauer anschauen
und melde mich später wieder.

Gruß, Davicito.
 
Naja, das hier ist doch wohl nicht dein ernst:

PHP:
 public function login($bn, $pw, $db)
        {        
            try
            {
                $dbConnection = @new mysqli('localhost', $bn , $pw, $db);
            }
        }

PHP:
$link = new LoginModel;
            $link->login($_POST['bn'], $_POST['pw'], $_POST['db']);
 
Hi alxy,

was meinst Du? Ich verstehe gerad nur Bahnhof. Vielleicht sehe ich gerade den Wald vor lauter Bäumen nicht. Also kannst Du zu den geposteten Code auch noch etwas erklären, warum das jetzt nicht mein Ernst sein soll?

Vielen Dank, Davicito.
 
Deine Datenbank-Verbindungsdaten kommen, wen ich das richtig überblicke, aus dem POST-array.
Das habe ich so noch nie gesehen und weiß auch nicht wofür das gut sein sollte? Jedenfalls hätte er damit auch zugriff auf Datenbanken des selben hosts bei bekannten zugangsdaten. Aber ich versteh generell nicht, was du damit bezweckst?
 
Zurück