Authentifizierung mit Zend_Auth
Anzeige Hier werben
Die Zend_Auth-Komponente vom Zend Framework bietet einem eine klare Struktur, wie man die Authentifizierung vornhemen kann. Die Komponente bietet HTTP-, Digest-, Datenbank-, LDAP- und eine OpenID-Authenfizierung. Im Ablauf der Authentifizierung unterscheiden sich diese Mechanismen nur in der Initialisierung des Zend_Auth-Objekts.
Für dieses Beispiel nutze ich die Authentifzierung gegen die Daten in einer Datenbank. In der Datenbank sind der Benutzername und das Passwort gespeichert. Das Passwort ist MD5 verschlüsselt.
Nun erstmal die grobe Struktur, wie ihr prüfen könnt, ob der aktuelle Besucher eingeloggt ist oder nicht.
Vorraussetzung
Damit ihr die Code-Beispiele genauso testen könnt, wie sie hier beschrieben sind, muss sich das Zend Framework in eurem include_path befinden. Es muss also ein Zend-Verzeichnis im include_path liegen.
Vorbereitung
Die Datenbankstruktur
1
2
3
4
5
6
7 | CREATE TABLE `example`.`user` (
`user_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(32) NOT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY (`username`)
);
|
Beispieldaten für die Datenbank
1 2 | INSERT INTO `example`.`user` (`username`, `password`) VALUES
('Max Mustermann', MD5('geheim'));
|
Ist der Besucher eingeloggt?
Code-Beispiel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php
require_once 'Zend/Auth.php';
$auth = Zend_Auth::getInstance();
require_once 'Zend/Auth/Storage/Session.php';
$storage = new Zend_Auth_Storage_Session;
$auth->setStorage($storage);
if ($auth->hasIdentity()) {
// eingeloggt
} else {
// nicht eingeloggt
}
?>
|
Erklärung des Beispiels
Als erstes besorgen wir uns eine Instanz von Zend_Auth. Das geschieht nicht über new Zend_Auth sondern über Zend_Auth::getInstance(), da es sich bei Zend_Auth um einen Singleton handelt. So kann man in der kompletten Anwendung sehr einfach auf das Objekt zurückgreifen.
Danach müssen wir sagen, wo die Informationen, ob ein Benutzer eingeloggt ist oder nicht, abgelegt sind. In diesem Beispiel nutzen wir Zend_Auth_Storage_Session. Die Informationen werden also in einer Session abgelegt. Diese Komponente kümmert sich auch von selbst darum, dass die Session gestartet wird. Ihr müsst euch also nicht selbst darum kümmern.
Nach diesen paar Zeilen könnte ihr nun mit $auth->hasIdentity() prüfen, ob der Benutzer eingeloggt ist, oder nicht. Diese Methode liefert TRUE zurück, wenn der Benutzer eingeloggt ist, FALSE wenn nicht.
Jetzt fehlt aber noch das Login ansich.
Das Login
Code-Beispiel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <?php
require_once 'Zend/Auth.php';
$auth = Zend_Auth::getInstance();
require_once 'Zend/Auth/Storage/Session.php';
$storage = new Zend_Auth_Storage_Session;
$auth->setStorage($storage);
require_once 'Zend/Db.php';
$database = Zend_Db::factory('PDO_MYSQL', array(
'host' => 'localhost',
'username' => 'db-username',
'password' => 'db-password',
'dbname' => 'example'
));
require_once 'Zend/Auth/Adapter/DbTable.php';
$adapter = new Zend_Auth_Adapter_DbTable(
$database, // Datenbankverbindung
'user', // Tabelle in der Datenbank (hier: example.user)
'username', // Spalte, in der der Benutzername abgelegt ist
'password', // Spalte, wo das Passwort abgelegt ist
'MD5(?)' // Passwort ist MD5 verschlüsselt
);
$adapter->setIdentity('Max Mustermann')->setCredential('geheim');
$result = $auth->authenticate($adapter);
if ($result->isValid())
{
echo "Erfolgreich eingeloggt.";
$storage->write($result->getResultRowObject(
null, 'password'
));
}
else
{
echo "Login fehlgeschlagen:<br />";
foreach ($result->getMessages() as $message) {
echo "- {$message}<br />";
}
}
?>
|
Erklärung des Beispiels
Zurerst brauchen wir nochmal die Zend_Auth-Komponente, damit bei der Authentifizierung klar ist, wohin, bei Erfolg, die Daten geschrieben werden müssen, dass der Benutzer eingeloggt ist.
Hier wird zuerst, mit Hilfe der Zend_Db-Komponente eine Datenbankverbindung hergestellt. Dazu wird im Hintergrund die MySQL-Abstraktion von PDO genutzt. Bei euch werden die einzelnen Parameter (host, username, password, dbname) an eure Datenbank angepasst werden.
Danach erstellen wir eine Instanz von Zend_Auth_Adapter_DbTable. Damit definieren wir, dass unsere Benutzerdaten in einer Tabelle in der Datenbank liegen. Als ersten Parameter übergeben wir die, zuvor erstellte, Datenbankverbindung. Der zweite Parameter definiert die Tabelle, wo die Benutzerdaten liegen. In diesem Beispiel liegen die Benutzerdaten in der Tabelle "example.user". Die folgenden zwei Parameter definieren die Namen der Spalten wo der Benutzername bzw. das Passwort abgespeichert sind. Der letzte Parameter gibt an, dass unsere Passwörter in der Datenbank MD5 verschlüsselt sind. Das Fragezeichen (?) ist wichtig, da die Zend_Auth_Adapter_DbTable-Komponente einen SQL-Query zusammenstellt, womit die Daten in der Datenbank überprüft werden können. Das Query enthält am Ende password=MD5("geheim"). Das Fragezeichen wird durch das Passwort ersetzt. Aber darum müsst ihr euch nicht kümmern.
Danach setzt ihr per setIdentity() den Benutzernamen, mit setCredential() das Passwort, des Benutzers, der sich soeben versucht einzuloggen. In diesem Beispiel habe ich nun auf ein Login-Formular etc. verzichtet. Ihr müsstet dann $_POST['username'] und $_POST['password'] oder ähnliches nutzen. Das kommt auf eure Anwendung an.
Nun weiss der Adapter, dass sich wer versucht einzuloggen. Also müssen wir die Prüfung starten. Das passiert mit dem Aufruf von $auth->authenticate($adapter). Damit wird in der Datenbank nach einem Benutzer gesucht, der "Max Mustermann" heisst und das Passwort "geheim" hat.
Ob die Suche nach einem passenden Benutzer erfolgreich war, könnt ihr mit $result->isValid() prüfen. Gibt die Methode TRUE zurück, so war die Authenfizierung erfolgreich. Gibt sie jedoch FALSE zurück, so wurde kein passender Benutzer gefunden. Dann könnt ihr mit $result->getMessages() herausfinden woran es gescheitert ist.
War die Authenfizierung erfolgreich, so müssen die Informationen noch in die Session geschrieben werden. Dafür nutzen wir $storage->write($result->getResultRowObject(null, 'password')). Mit dem ersten Parameter, der bei diesem Beispiel NULL ist, können die Spalten definiert werden, welche in die Session geschrieben werden sollen. Mit dem zweiten Parameter kann man definieren, welche Spalten nicht in die Session geschrieben werden sollen. So werden alle Informationen aus der Datenbanktabelle in die Session geschrieben, ausser der die Spalte "password". Das Passwort ist zwar verschlüsselt, aber trotzdem hat das Passwort dort nichts zu suchen.
Erweiterungen
Benutzer können aktiviert bzw. deaktiviert werden
Können Benutzer aktiviert bzw. deaktiviert werden und gibt es dafür in der Datenbanktabelle z.B. eine Spalte (z.B. active), so kann man beim Instanzieren der Zend_Auth_Adapter_DbTable-Komponente eine kleine Anpassung vornehmen, um den Status zu prüfen.
1
2
3
4
5
6
7
8 | CREATE TABLE `example`.`user` (
`user_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(32) NOT NULL,
`active` TINYINT(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`user_id`),
UNIQUE KEY (`username`)
);
|
Habt ihr die Tabelle bereits aus dem Beispiel weiter oben in der Datenbank (ohne active-Spalte), so könnt ihr die Spalte auch nachträglich einfügen.
1 | ALTER TABLE `example`.`user` ADD COLUMN `active` TINYINT(1) NOT NULL DEFAUL '0';
|
Nun muss auch der Adapter angepasst werden.
1
2
3
4
5
6
7 | $adapter = new Zend_Auth_Adapter_DbTable(
$database,
'user',
'username',
'password',
'MD5(?) AND active=1'
);
|
Nun muss der Wert in der "active"-Spalte 1 sein, damit der Benutzer sich einloggen kann.
Verwandte Artikel
Diese Seite kann von jedem registrierten Benutzer bearbeitet werden. Bisher haben 2 Personen an der Seite "Authentifizierung mit Zend_Auth" mitgewirkt.
Sie haben einen Fehler entdeckt oder möchten etwas ergänzen? Dann können Sie nach der Anmeldung "Authentifizierung mit Zend_Auth" hier bearbeiten.
-
arbeitet bei der Adcloud GmbH als Software Engineer und beschäftigt sich bereits seit dem Jahr 2000 mit der Entwicklung von dynamischen Internetseiten.
-
Student der Biochemie und seit einigen Jahren im Hobby-Entwicklerbereich tätig. Stärken in XHTML/CSS und PHP, alles was mit Grafik zu tun hat, gehört nicht dazu.


Fehler im Beispiel-Code
Du hast einen Fehler im Beispiel-Code.
In Zeile 34, statt
$storage->write($result->getResultRowObject(null,'password'));
soll
$storage->write($adapter->getResultRowObject(null, 'password'));
stehen.
Zend Framework VERSION = '1.9.7'
Re: Fehler im Beispiel-Code
Oh, da hast du Recht. Ich kann den Artikel aber nicht bearbeiten. Beim Speichern bekomme ich immer einen Fehler. Ich schreib diesbezüglich mal einen der Admins an.
Danke für den Hinweis ;)
Sehr schoen!
Gefällt mir sehr gut, dass ich hier mal was zur Anwendung des Zend Frameworks lese, da will ich auch bald mal ran. Kann man die Komponente Zend_Auth auch gegen eine Datei nutzen, etwa eine XML oder Textdatei. Wenn du da das Beispiel erweiterst, oder einfach Nein sagst, oder mir einen Link gibst, wäre ich dir sehr dankbar. Danke schon mal für den bisherigen Artikel.
Re: Sehr schoen!
Die Authentifizierung gegen eine Text- oder XML-Datei kenne ich soweit nun nicht, aber du kannst, wie hier beschrieben, deinen eigenen Adapter schreiben (z.B. My_Auth_Adapter_Xml o.ä.), indem du die authenticate()-Methode mit Leben füllst, wie du es brauchst.
Wenn du einen sauberen Ansatz der Implementierung eines solchen Adapters hast, kannst du ihn ja vielleicht als Erweiterung fürs Framework vorschlagen. Sind aber beides Verfahren, die eher performancelastig sind, wenn es viele Benutzer gibt, da immer die komplette Datei gelesen werden müsste.