Zend_Auth adapter with Doctrine
Here is an example of a Zend_Auth adapter for the Zend Framework that uses Doctrine as the ORM.
<?php
/**
* Zend_Auth adapter for an extended Doctrine users record.
*
*@package PaloVerde
*@author Sam McCallum <sam@palo-verde.us>
*/
class PaloVerde_Auth implements Zend_Auth_Adapter_Interface {
public $username;
public $password;
public $user;
const NOT_FOUND_MESSAGE = "The username you entered could not be found.";
const CREDINTIALS_MESSAGE = "The password you entered is not correct.";
const UNKNOWN_FAILURE = "Authentication failed for an unknown reason.";
public function __construct($username, $password) {
$this->username = $username;
$this->password = $password;
}
/**
* Zend_Auth hook.
*/
public function authenticate() {
try {
$this->user = Users::authenticate($this->username, $this->password);
} catch (Exception $e) {
if ($e->getMessage() == Users::NOT_FOUND) {
return $this->notFound();
}
if ($e->getMessage() == Users::PASSWORD_MISMATCH) {
return $this->passwordMismatch();
}
return $this->failed($e);
}
return $this->success();
}
/**
* Factory for Zend_Auth_Result
*
*@param integer The Result code, see Zend_Auth_Result
*@param mixed The Message, can be a string or array
*@return Zend_Auth_Result
*/
public function result($code, $messages = array()) {
if (!is_array($messages)) {
$messages = array($messages);
}
return new Zend_Auth_Result(
$code,
$this->username,
$messages
);
}
/**
* "User not found" wrapper for $this->result()
*/
public function notFound() {
return $this->result(Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND,self::NOT_FOUND_MESSAGE);
}
/**
* "Password does not match" wrapper for $this->result()
*/
public function passwordMismatch() {
return $this->result(Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND,self::CREDINTIALS_MESSAGE);
}
/**
* General or Unknown failure wrapper for $this->result()
*/
public function failed(Exception $e) {
return $this->result(Zend_Auth_Result::FAILURE, self::UNKNOWN_FAILURE);
}
/**
* "Success" wrapper for $this->result()
*/
public function success() {
return $this->result(Zend_Auth_Result::SUCCESS);
}
}
?>
So... basically we call a method on the model Users::authenticate(username, password), which returns a valid user object on success or throws and exception on fail, we catch the exceptions or success and wrap then in the Zend_Auth_Result container, and pass it on.
Here is the Doctrine Record
<?php
class Users extends Doctrine_Record {
const NOT_FOUND = 1;
const PASSWORD_MISMATCH = 2;
public function setTableDefinition() {
$this->hasColumn('name','text', array('unique', 'notblank','nospace'));
$this->hasColumn('pass','text', array('notblank','nospace'));
$this->hasColumn('email','text', array('email','notblank','nospace'));
}
public static function authenticate($username, $password) {
$md5_pass = md5($password);
$theUser = Doctrine::getTable('Users')->findOneByName($username);
if (!$theUser) {
throw new Exception(self::NOT_FOUND);
}
if ($theUser->pass != $md5_pass) {
throw new Exception(self::PASSWORD_MISMATCH);
}
return $theUser->toArray();
}
}
?>
That should be pretty self explanatory if you are used to Doctrine. We try an get a user with the passed username. If they exist and the password matches, then return it, otherwise throw the correct exception.
2 comments
Hi, I have a problem with this, Zend_Auth generate an instance after I complete data to login but when I change or redirect to another page the instance seems to loose and I get an error of Zend_Session::start() when I try to to know if Zend_Auth::getInstance()->hasIdentity() If I do a var_dump(Zend_Auth::getInstance()); I get object(Zend_Auth)#56 (1) { ["_storage:protected"]=> NULL } How can I accomplish to persist data in every request ? Thank you
— martin Fri, 29 Jan 2010
Thanks for the example, I modified it some to fit my application but your implementation was exactly what I needed. Many thanks.
— ahmad Sun, 27 Sep 2009