ZendFramework: Basic/Digest-Auth über Zend_Db
Möchte mit dem ZendFramework eine HTTP Basic oder Diggest Authentifaktion erstellen bietet das Framework und die Klasse Zend_Auth_Adapter_Http derzeit nur die Möglichkeit die Userdaten mit Textdateien abzugleichen.
Doch gerade Basic und Diggest Authentifikation über Datenbanken ist so ein Fall, denn ich derzeit viel zu oft brauche. Um es kurz für andere festzuhalten, die eventuell auch mal in die Situation kommen: Das ganze zu implementieren sind effektiv ~5 Zeilen Code:
class Zend_Auth_Adapter_Http_Resolver_DbTable implements Zend_Auth_Adapter_Http_Resolver_Interface { protected $_dbh = null; public function __construct(Zend_Db $dbh) { $this->_dbh = $dbh; } public function resolve($username, $realm) { $stmt = $this->_dbh->prepare( 'SELECT password FROM users WHERE username = :username LIMIT 1' ); $stmt->bindParam(':username', $username); $stmt->execute(); // Gibt das Passwort des Users zurueck return $stmt->fetch(PDO::FETCH_OBJ)->password; } }
Benutzt wird das ganze dann wie folgt:
$auth = new Zend_Auth_Adapter_Http(array( 'accept_schemes' => 'basic', 'realm' => 'area51' )); // Unsere Helferklasse als Resolver für das Passwort einbinden. // Als Parameter für __construct wird eine Zend_Db Instanz mit übergeben $auth->setBasicResolver( new Zend_Auth_Adapter_Http_Resolver_DbTable(Zend_Db::factory($config)) ); // Benötigte Response und Request Klassen starten $auth->setRequest($request = new Zend_Controller_Request_Http()); $auth->setResponse($response = new Zend_Controller_Response_Http()); // Die eigentliche Authentifikation $result = $auth->authenticate(); // Erscheint beim klick auf "abbrechen" if (!$result->isValid()) die("Try again!"); $response->sendResponse();
Das ganze funktioniert natürlich auch mit HTTP Digest. Da hier das Passwort aber verschlüsselt übertragen wird, muss eine Kleinigkeit angepasst werden:
public function resolve($username, $realm) { ... // MD5 Hash von "benutzername:realm:passwort" return md5($username.':'.$realm.':'.$stmt->fetch(PDO::FETCH_OBJ)->password); }