PHP Finde den Fehler nicht (OOP)

selberbauer

Captain
Registriert
Juni 2009
Beiträge
3.604
Hallo,
ich habe eine Klasse, welche für mich die Session Verwaltung übernimmt.
Beim aufrufen der Authentifications-Methode muss irgendwas schief laufen, ich weiß aber nicht was.

PHP:
<?php

class auth {
	private $user;
	private $pass;
	private $hash;
	
	private $key_1;
	private $key_2;

	private $link_1 = 'secret.php';
	private $link_2 = 'index.php';
	
	public function __construct($_POST) {
	    $this->key();
	    if($this->valid($_POST['user'], $_POST['pass'])) {
	    	$this->auth();
	    }
	}
	
	private function key() {
		$rand  = hash('SHA512', rand());
		$str   = str_split($random, 32);
		$this->key_1 = $str[0].date('m.d.Y H:i:s').$str[1];
		$this->key_2 = $str[2].$_SERVER['HTTP_USER_AGENT'].$str[3];
	}

	private function valid($username, $password) {
		$_SESSION['state'] = FALSE;
		if(isset($username, $password)) {
			$this->user = $username;
			$this->user = $password;
			$this->hash = hash('SHA512', $this->pass);
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	public function auth() {
		$db = new mysqli(HOST, USER, PASS, DATA);
		if($stmt = $db->prepare('SELECT user, hash, status FROM user WHERE user = ? AND hash = ? AND status = 1')) {
			$stmt->bind_param('ss', $this->user, $this->hash);
			$stmt->execute();
			$stmt->store_result();
			$state = $stmt->num_rows();
			$stmt->close();
		}
		echo $state;
		if($state == 1) {
			$_SESSION['state'] = TRUE;
			$_SESSION['time']  = date('m.d.Y H:i:s');
			$_SESSION['one']   = $this->key_1;
			$_SESSION['two']   = $this->key_2;
			header('Location: '.$this->link_1);
			exit();
		} else {
			return FALSE;
		}
	}
	
	public function ini() {
		session_start();
		if( (!$_SESSION['state']) OR ($_SESSION['one'] != $this->key_1) OR ($_SESSION['two'] != $this->key_2) ) {
			header('Location: '.$link_1);
			exit();
		}
	}
	
	public function logout() {
		session_start();
		session_destroy();
		session_unset();
	}
}			
	
?>
 
Gibt er denn State aus oder kommt er gar nicht so weit?
"Irgendwas schief" ist ziemlich vage.
 
also ich würde spontan sagen das
Code:
public function __construct($_POST) {

einen efhler erzeuge könnte da evtl. die globale variable $_POST überschrieben wird.

mach mal lieber

Code:
public function __construct($p) {
	    $this->key();
	    if($this->valid($p['user'], $p['pass'])) {
	    	$this->auth();
	    }
	}

und aufrufen dann mit

Code:
$a = new auth($_POST);


außerdem solltest du die session nicht in den methoden starten sondern ganz oben über der klassen definition. Falls schon ein header gesnedet wurde gibt das sonst einen fehler


außerdem kannst du den isset() teil bei valid weglassen.
In PHP müssen immer zwingend alle variablen an eine Methode übergeben werden (es sei denn man gibt denen einen stadart wert mit (was hier nicht passiert)), also gibt es entweder dirket einen Fehler beim aufruf und isset wird nicht ausgeführt oder aber man weiß das die beiden Variablen da sind und prüft trotzdem nochmal.
Zumal die funktion private ist,also nur von der klasse selber aufgerufen wird, da würde es also reichen einmal ganz zu beginn prüfen ob die werte vorhanden sind.

Evtl. wäre dort ein Test auf NULL oder "" (leer string) ganz gut. Am besten in verbindung mit trim().

in der auth metjode frage ich mich wo $db = new mysqli(HOST, USER, PASS, DATA); da die parameter herkommen?
 
Zuletzt bearbeitet:
selberbauer schrieb:
Hallo,
ich habe eine Klasse, welche für mich die Session Verwaltung übernimmt.
Beim aufrufen der Authentifications-Methode muss irgendwas schief laufen, ich weiß aber nicht was.

PHP:
<?php


	private function valid($username, $password) {
		$_SESSION['state'] = FALSE;
		if(isset($username, $password)) {
			$this->user = $username;
			$this->user = $password;
			$this->hash = hash('SHA512', $this->pass);
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
?>

Weiß nicht, ob das das Problem ist, aber hier ist zumindest ein Wurm drin ;)

Grüße

Brainfart
 
um es mal nicht alzu spannend zu machen, setzt du $this->user einmal = $username und einmal = $password
 
Danke für die schnellen Antworten!

@Mercsen
außerdem kannst du den isset() teil bei valid weglassen.
In PHP müssen immer zwingend alle variablen an eine Methode übergeben werden (es sei denn man gibt denen einen stadart wert mit (was hier nicht passiert)), also gibt es entweder dirket einen Fehler beim aufruf und isset wird nicht ausgeführt oder aber man weiß das die beiden Variablen da sind und prüft trotzdem nochmal.
Zumal die funktion private ist,also nur von der klasse selber aufgerufen wird, da würde es also reichen einmal ganz zu beginn prüfen ob die werte vorhanden sind.

Evtl. wäre dort ein Test auf NULL oder "" (leer string) ganz gut. Am besten in verbindung mit trim().
Das verstehe ich jetzt noch nicht so ganz. Soll ich die variablen im Konstruktor übergeben?

Habe das hoffentlich soweit jetzt alles korrigiert.
@Brainfart
Das war es doch oder?

PHP:
<?php

session_start();

class auth {
	private $user;
	private $pass;
	private $hash;
	
	private $key_1;
	private $key_2;

	private $link_1 = 'secret.php';
	private $link_2 = 'index.php';
	
	public function __construct($post) {
	    $this->key();
	    if($this->valid($post['user'], $post['pass'])) {
	    	$this->auth();
	    }
	}
	
	private function key() {
		$rand  = hash('SHA512', rand());
		$str   = str_split($random, 32);
		$this->key_1 = $str[0].date('m.d.Y H:i:s').$str[1];
		$this->key_2 = $str[2].$_SERVER['HTTP_USER_AGENT'].$str[3];
	}

	private function valid($username, $password) {
		$_SESSION['state'] = FALSE;
		if(isset($username, $password)) {
			$this->user = $username;
			$this->pass = $password;
			$this->hash = hash('SHA512', $this->pass);
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	public function auth() {
		$db = new mysqli(HOST, USER, PASS, DATA);
		if($stmt = $db->prepare('SELECT user, hash, status FROM user WHERE user = ? AND hash = ? AND status = 1')) {
			$stmt->bind_param('ss', $this->user, $this->hash);
			$stmt->execute();
			$stmt->store_result();
			$state = $stmt->num_rows();
			$stmt->close();
		}
		echo $state;
		if($state == 1) {
			$_SESSION['state'] = TRUE;
			$_SESSION['time']  = date('m.d.Y H:i:s');
			$_SESSION['one']   = $this->key_1;
			$_SESSION['two']   = $this->key_2;
			header('Location: '.$this->link_1);
			exit();
		} else {
			return FALSE;
		}
	}
	
	public function ini() {
		session_start();
		if( (!$_SESSION['state']) OR ($_SESSION['one'] != $this->key_1) OR ($_SESSION['two'] != $this->key_2) ) {
			header('Location: '.$link_1);
			exit();
		}
	}
	
	public function logout() {
		session_start();
		session_destroy();
		session_unset();
	}
}			
	
?>

Der Parser meldet jetzt "nur" noch folgendes:
Code:
Notice: A session had already been started - ignoring session_start() in /home/bodo/Projekte/lang/PHP/authentification/index.php on line 6 Notice: Undefined variable: random in /home/bodo/Projekte/lang/PHP/authentification/class.inc.php on line 25 Notice: Undefined offset: 1 in /home/bodo/Projekte/lang/PHP/authentification/class.inc.php on line 26 Notice: Undefined offset: 2 in /home/bodo/Projekte/lang/PHP/authentification/class.inc.php on line 27 Notice: Undefined offset: 3 in /home/bodo/Projekte/lang/PHP/authentification/class.inc.php on line 27 Notice: Undefined index: user in /home/bodo/Projekte/lang/PHP/authentification/class.inc.php on line 18 Notice: Undefined index: pass in /home/bodo/Projekte/lang/PHP/authentification/class.inc.php on line 18 Fatal error: Call to private method auth::valid() from context '' in /home/bodo/Projekte/lang/PHP/authentification/index.php on line 10
 
ichmeine das wie folgt:

deine methode valid erwartet 2 parameter, $username & $password

isset() prüft nur ob die variablen nicht auf NULL zeigen und existieren.
Dass sie existieren weißt du ja aber schon, denn der methoden aufruf würde abgebrochen werden wenn du nicht alle parameter an die methode übergibst.

du könntest jetzt halt statt isset($username) sowas machen wie

Code:
if(trim($username) != "")

ist aber nicht weiter dramatisch das kann auch so bleiben, trim ist mitunter sogar ein wneig langsamer als trim.

der erste fehler sagt dir nur das schon eine session gestartet wurde, also gehe ich mal davon aus das in index.php auch ein session_start() vorhanden ist.
auch wenn ich diese fehlereldung noch nie gesehen habe, kannst du durch geschickte verwenundung von if + session_id() aber umgehen ;)

dder zweite fehler sagt das die variable $random in zeile 25 nicht existiert, du wolltest wohl die variable $rand nehmen,

der dritte fehler sagt dir das $str keine 2 elemente enthält.
lass dir $str ambestenmal mit print_r($str) ausgeben.

fehler 4 sagt dir das in $post kein key mit dem wert 'pass' existiert, also mal gucken was ankommt.
print_r($post) hilft hier! ;)

der letze fehler sagt das du vermutlich so etwas gemacht hast

Code:
$a = new auth();
$a->auth();

das geht nicht weil auth eine private methode der klasse auth ist und nicht vonaußen aufgerufen werden kann
 
deine methode valid erwartet 2 parameter, $username & $password

isset() prüft nur ob die variablen nicht auf NULL zeigen und existieren.
Dass sie existieren weißt du ja aber schon, denn der methoden aufruf würde abgebrochen werden wenn du nicht alle parameter an die methode übergibst.

du könntest jetzt halt statt isset($username) sowas machen wie
Jetzt verstehe ich es ;)
ist aber nicht weiter dramatisch das kann auch so bleiben, trim ist mitunter sogar ein wneig langsamer als trim.
isset langsamer als trim?

der erste fehler sagt dir nur das schon eine session gestartet wurde, also gehe ich mal davon aus das in index.php auch ein session_start() vorhanden ist.
auch wenn ich diese fehlereldung noch nie gesehen habe, kannst du durch geschickte verwenundung von if + session_id() aber umgehen
Richtig ^^
Ist es nicht besser "session_start();" über index.php aufzurufen?

dder zweite fehler sagt das die variable $random in zeile 25 nicht existiert, du wolltest wohl die variable $rand nehmen,

der dritte fehler sagt dir das $str keine 2 elemente enthält.
lass dir $str ambestenmal mit print_r($str) ausgeben.
Beide zusammen ergeben die Lösung ;)

der letze fehler sagt das du vermutlich so etwas gemacht hast
Auch richtig gefolgert :D

An sich funktioniert die Klasse jetzt einwandfrei!
Was kann man jetzt semantisch noch verbessern?

Gruß
 
ja session_start() reicht im index.php aus, dann darfst es aber nicht mehr in deiner klasse verwenden, bzw. da nur wenn die session noch nicht gestartet wurde.

das kann man mit
if(session_id() == "")
testen

außerdem meinte ich das trim langsamer ist als isset da es den gesamten String prüfen muss, während isset nur guckt ob die variable != NULL ist (und existiert aber das hängt mit dem internen variablen counter von php zusammen)

ansonsten gibts nicht viel.

Ich finde die header() methode ein wenig kritisch, denn dadurch das du dich in der Klasse befindest kannst du nicht sicher sein das schon ein header gesendet wurde.

Lasse da lieber false zurück geben und das script reagiert dann entsprechend. Vlt. statt einer weiterleitung einfach die Fehlerseite per include einbinden?

und es ist natürlich verlockend variablen wie key_1, link_2 etc. zu benutzen.
Sinnvoller wären aber arrays, da diese variabler sind, es sei denn natürlich bei dir bleibt es immer nur bei 2 seiten / keys

aber dann wären eindeutigere namen besser, wie link_index, link_secret o.ä., macht das erkennen was in der variablen steht auf jedenfall leichter. In 2 Monaten weißt sicher nimma was link_1 und key_1 denn machen.

Was zu Kommentaren führt, PHP unterstpützt soetwas wie jDoc.

dsa geht z.b. wie folgt:

PHP:
/**
* Diese Klasse macht dieses und jenes 
*/

class test {
    /**
    * Setzt die id
    * @param $id die id 
   * @return array ein array mit werten
    * /
   public function setId($id) {
         return array("a","b");
   }
}
[/code]

eine gescheite IDE zeigt dir bei der verwendung an was die methode macht und was sie für parameter erwartet bzw. welchen typ der return wert hat.

@throws kann es auch und ermöglicht es so methoden zu deklarieren die eine exception werfen können, was PHP von haus aus leider nicht unterstützt.

Ich kann dir nur NetBeans empfehlen, gibt keine bessere IDE für PHP
 
Verstehe.
Ich finde die header() methode ein wenig kritisch, denn dadurch das du dich in der Klasse befindest kannst du nicht sicher sein das schon ein header gesendet wurde.

Lasse da lieber false zurück geben und das script reagiert dann entsprechend. Vlt. statt einer weiterleitung einfach die Fehlerseite per include einbinden?
Wäre es nicht auch besser, die ver. Funtkionsaufrufe aus den Konstruktor zu nehmen?
Das heisst, dass ich die Sachen so aufrufe:
PHP:
<?php

$auth = new auth();
if($auth->valid()) {
    $auth->key();
    if(!$auth->auth()) {
        include('login.php');
   } else {
       include('index.php');
}

?>

Und evtl., dass auth() die key()-Methode bei TRUE aufruft?
Weil sonst müsste man bei öfterer Verwendung ständig ein neues Objekt erstellen und ich kann je nach Rückgabewert dann reagieren, siehe oben

nd es ist natürlich verlockend variablen wie key_1, link_2 etc. zu benutzen.
Sinnvoller wären aber arrays, da diese variabler sind, es sei denn natürlich bei dir bleibt es immer nur bei 2 seiten / keys
Bei der Verwendung von Arrays kriege ich immer "fatal errors"

Ich kann dir nur NetBeans empfehlen, gibt keine bessere IDE für PHP
Ich arbeite momentan mit VIM/Gedit und danneben einem Browser, der den lokalen LAMP aufruft. Eigentlich sehr angenehm, habe mich bereits bei IDEs umgesehen, aber die "überfordern" mich eher als zu helfen
 
NB ist wirklich eine gewaltige IDE aber für mich mittlerweile wirklich unverzichtbar geworden.

ich würde dir desweiteren davon abraten in der klasse den include befehl zu verwenden denn intern läuft dabei folgendes ab:

1. Script startet....
2. Klasse wird aufgerufen
3. If abfrage schlägt fehl
4. index.php wird per include eingebunden
5. index.php wird KOMPLETT abgerarbeitet
6. klasse wird weiter abgearbeitet

d.h. mitten drinne im code wird plötzlich neuer code eingefügt undverarbeitet ehe der ursprüngliche teil fortgesetzt wird.

jetzt hast du es zwar nicht in der klasse und alle funktionsuafrufe aus dem Konstruktor rausgneommen aber ich würde die dort lieber wieder rein tun.

so musst du dich um alles selber kümmern, sinnvollerist es aber wenn du z.b. nur ein Objekt erzeugen müsstest und der macht alles so weit fertig.

Anschließend fragst du dann mit z.b. $a->erfolgreich() ab ob alles glatt gegangen ist.

erfolgreich gibt dann true zurpck wenn ja oder false falls irgendeine methode fehlschlug und da lädst dann die fehlerbehandlung rein.

hast mal ein beispiel wo du bei einem array einen fatal error bekommst?

Über kurz oder lang führt nämlich kein weg an arrays vorbei ;)
 
Wegen den arrays:
PHP:
<?php

class auth {
	private $user;
	private $pass;
	private $hash;
	
	private $key = array()

	private $link_1 = 'secret.php';
	private $link_2 = 'index.php';
	
	public function __construct($post) {
	    $this->key();
	    if($this->valid($post['user'], $post['pass'])) {
	    	$this->auth();
	    }
	}
	
	private function key() {
		$rand  = hash('SHA512', rand());
		$str   = str_split($rand, 32);
		$this->key_1 = $str[0].date('m.d.Y H:i:s').$str[1];
		$this->key_2 = $str[2].$_SERVER['HTTP_USER_AGENT'].$str[3];
	}

	private function valid($username, $password) {
		$_SESSION['state'] = FALSE;
		if(trim($username) != '' AND trim($password) != '') {
			$this->user = $username;
			$this->pass = $password;
			$this->hash = hash('SHA512', $this->pass);
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	public function auth() {
		$db = new mysqli(HOST, USER, PASS, DATA);
		if($stmt = $db->prepare('SELECT user, hash, status FROM user WHERE user = ? AND hash = ? AND status = 1')) {
			$stmt->bind_param('ss', $this->user, $this->hash);
			$stmt->execute();
			$stmt->store_result();
			$state = $stmt->num_rows();
			$stmt->close();
		}
		if($state == 1) {
			$_SESSION['state'] = TRUE;
			$_SESSION['time']  = date('m.d.Y H:i:s');
			$_SESSION['one']   = $this->key[1];
			$_SESSION['two']   = $this->key[2];
			header('Location: '.$this->link_1);
			exit();
		} else {
			return FALSE;
		}
	}
	
	public function ini() {
		session_start();
		if( (!$_SESSION['state']) OR ($_SESSION['one'] != $this->key[1]) OR ($_SESSION['two'] != $this->key[2]) ) {
			header('Location: '.$link_1);
			exit();
		}
	}
	
	public function logout() {
		session_start();
		session_destroy();
		session_unset();
	}
}			
	
?>

Code:
Parse error: syntax error, unexpected T_PRIVATE, expecting ',' or ';' in /home/bodo/Projekte/lang/PHP/authentification/class.inc.php on line 10

Wegen der anderen Sache:
Ich schreibe die Klasse mal so um, wie ich es mir noch vorgestellt habe.
Ergänzung ()

Also die Variante mit den manuellen Aufruf wäre eigentlich skalierbarer:

PHP:
<?php

include('config.inc.php');
include('class.inc.php');

session_start();


$auth = new auth();
if($auth->valid($_POST['user'], $_POST['pass'])) {
	if($auth->auth()) {
		header('Location: secret.php');
	} else {
		$output = 'Fehler bei Authentifizierung';
	}
}
?>

<!DOCTYPE html>
<html>

PHP:
<?php

class auth {
	private $user;
	private $pass;
	private $hash;
	
	private $key_1;
	private $key_2;

	private $link_1 = 'secret.php';
	private $link_2 = 'index.php';
	
	private function key() {
		$rand  = hash('SHA512', rand());
		$str   = str_split($rand, 32);
		$this->key_1 = $str[0].date('m.d.Y H:i:s').$str[1];
		$this->key_2 = $str[2].$_SERVER['HTTP_USER_AGENT'].$str[3];
	}

	public function valid($username, $password) {
		$_SESSION['state'] = FALSE;
		if(trim($username) != '' AND trim($password) != '') {
			$this->user = $username;
			$this->pass = $password;
			$this->hash = hash('SHA512', $this->pass);
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	public function auth() {
		$db = new mysqli(HOST, USER, PASS, DATA);
		if($stmt = $db->prepare('SELECT user, hash, status FROM user WHERE user = ? AND hash = ? AND status = 1')) {
			$stmt->bind_param('ss', $this->user, $this->hash);
			$stmt->execute();
			$stmt->store_result();
			$state = $stmt->num_rows();
			$stmt->close();
		}
		if($state == 1) {
			$this->key();
			$_SESSION['state'] = TRUE;
			$_SESSION['time']  = date('m.d.Y H:i:s');
			$_SESSION['one']   = $this->key_1;
			$_SESSION['two']   = $this->key_2;
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	public function ini() {
		session_start();
		if( (!$_SESSION['state']) OR ($_SESSION['one'] != $this->key_1) OR ($_SESSION['two'] != $this->key_2) ) {
			return FALSE;
		} else {
			return TRUE;
		}
	}
	
	public function logout() {
		session_destroy();
		session_unset();
		header('Location: index.php');
	}
}			
	
?>
Ergänzung ()

Was kann man an der Klasse noch verbessern?

Wo stecken Design Fehler?

Gruß
 
Sofern erwünscht, würde ich noch Ausnahmebehandlung implementieren.

Auch würde ich die logischen Operatoren anpassen. Hintergrund ist der, dass man so den Sourcecode schneller nach SQL oder PHP Operatoren durchsuchen kann, falls dies mal der Fall sein sollte. Ist aber Geschmackssache und kein Fehler.

Vorher
PHP:
if(trim($username) != '' AND trim($password) != '') {

Nachher
PHP:
if(trim($username) != '' && trim($password) != '') {

Dann werden ja Konstanten für die Verbindungsparameter zum MySQL-Server in der config.inc.php definiert. Warum dann nicht auch $link_1 und $link_2 als Konstante in diese Datei auslagern? So brauch man im bedarfsfall nur in der Konfigurationsdatei Werte anpassen, und muss sich nicht bestehende Klassen arbeiten.

Zum Guten Schluss wäre auch eine Kommentierung (Doxygen-Stil) des Quellcodes (Klassen, Methoden) nicht verkehrt. Das erleichtert anderen Entwicklern das Lesen und Verstehen von Klassen / Methoden, ohne diese selbst erst genau betrachtet zu haben. Hilft besonders, wenn man APIs entwickelt und Webservices anderen zur Verfügung stellt.

Ansonsten gibt es m. E. nicht wirklich weiteren Optimierungsbedarf. Ist zwar nicht MVC und auf eine weitesgehende Trennung von PHP und HTML wird hier verzichtet, ist aber jedem selbst überlassen.
 
Dann werden ja Konstanten für die Verbindungsparameter zum MySQL-Server in der config.inc.php definiert. Warum dann nicht auch $link_1 und $link_2 als Konstante in diese Datei auslagern? So brauch man im bedarfsfall nur in der Konfigurationsdatei Werte anpassen, und muss sich nicht bestehende Klassen arbeiten.
Ich habe mal das Konzept überarbeitet:
index.php prüft ob authentifiziert, wenn nein wird login.php geladen, so fallen die links weg.

Ist zwar nicht MVC und auf eine weitesgehende Trennung von PHP und HTML wird hier verzichtet, ist aber jedem selbst überlassen.
Erfolgt die Trennung nicht mittels TRUE, FALSE in den Funktionen?




Desweiteren besteht das Problem, dass ich einfach so auf den geheimen Bereich zugreifen kann, ohne angemeldet zu sein:
index.php
PHP:
<?php

include('config.inc.php');
include('class.inc.php');

if(!$auth = new auth()) {
	include('Location: login.php');
}

if($_POST['logout']) {
	$auth->logout();
}

include('secret.tpl');
	

?>

login.php
PHP:
<?php

include('config.inc.php');
include('class.inc.php');

$auth = new auth();
if($auth->valid($_POST['user'], $_POST['pass'])) {
	if($auth->auth()) {
		echo 'hank';
		header('Location: index.php');
	} else {
		$output = 'Fehler bei Authentifizierung';
	}
}

include('login.tpl');
?>

class.inc.php
PHP:
<?php

class auth {
	/**
	 * Definition der Klassenvariablen
	 * - Zugangsdaten für alle Funktionen in der Klasse zugängig
	 * - Zwischenspeicher der generierten Keys
	 */
	private $user;
	private $pass;
	private $hash;
	
	private $key_1;
	private $key_2;
	
	/**
	 * Konstruktor
	 * Prüft ob $_SESSION Schlüssel valide sind
	 */	
	public function __construct() {
		session_start();
		if( (!$_SESSION['state']) || ($_SESSION['one'] != $this->key_1) || ($_SESSION['two'] != $this->key_2) ) {
			return FALSE;
		} else {
			return TRUE;
		}
	}
	
	/**
	 * Generiert die Schlüssel für $_SESSION
	 * Erzeugung eines Hash aus zufälliger Zahl
	 * Teilung des Hashes in vier gleichgroße Teile
	 * Einsetzung der Zeit und der Browser ID zur identfizierung
	 * geschützt durch Hash
	 */
	private function key() {
		$rand  = hash('SHA512', rand());
		$str   = str_split($rand, 32);
		$this->key_1 = $str[0].date('m.d.Y H:i:s').$str[1];
		$this->key_2 = $str[2].$_SERVER['HTTP_USER_AGENT'].$str[3];
	}

	/**
	 * Prüft ob die Benutzereingabe valide war,
	 * falls ja, werden die Eingaben in die Klassenvariablen geladen
	 */
	public function valid($username, $password) {
		$_SESSION['state'] = FALSE;
		if(trim($username) != '' && trim($password) != '') {
			$this->user = $username;
			$this->pass = $password;
			$this->hash = hash('SHA512', $this->pass);
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	/**
	 * Prüft ob der Benutzer vorhanden ist
	 * Abfrage der Datenbank mittels prepared statement
	 * Falls Benutzer vorhanden Überweisung von $_SESSION
	 */
	public function auth() {
		$db = new mysqli(HOST, USER, PASS, DATA);
		if($stmt = $db->prepare('SELECT user, hash, status FROM user WHERE user = ? AND hash = ? AND status = 1')) {
			$stmt->bind_param('ss', $this->user, $this->hash);
			$stmt->execute();
			$stmt->store_result();
			$state = $stmt->num_rows();
			$stmt->close();
		}
		if($state == 1) {
			$this->key();
			$_SESSION['state'] = TRUE;
			$_SESSION['time']  = date('m.d.Y H:i:s');
			$_SESSION['one']   = $this->key_1;
			$_SESSION['two']   = $this->key_2;
			return TRUE;
		} else {
			return FALSE;
		}
	}
	
	/**
	 * Meldet den Benutzer ab
	 * Zerstört alle Session abhängigen Variablen
	 */
	public function logout() {
		session_destroy();
		session_unset();
		header('Location: login.php');
	}
}
 
Zurück
Oben