Authentication service
This is a followup to my previous post “ZF Authentication using Doctrine“. After posting my implementation of using a ZendX doctrine auth adapter. I got some feedback from Jon Lebensold from ZendCasts. The issue raised is that my implementation makes the controller fat, which is considered as a bad practice. I cannot agree more on that. So … I tried to refactor the code and come up with the introduction of a service layer class named “AuthenticationService”.
Now the LoginController class is made thinner with the following code.
public function loginAction()
{
$authService = new Model_AuthenticationService();
if($authService->isAuthenticated() == true) {
$this->_redirect('/index');
}
if($this->getRequest()->isPost()) {
$this->view->headTitle('Login');
// collect the data from the user
$loginUsername = $this->getRequest()->getParam('username', '');
$loginPassword = $this->getRequest()->getParam('password', '');
$authResult = $authService->authenticate(
$loginUsername,
$loginPassword
);
if($authResult == true) {
// auth good, do your logic
}
else {
// auth bad, do your logic
}
} else {
$this->_redirect('/login');
}
}
Code for AuthenticationService.php
class Model_AuthenticationService
{
private $_authenticationMessage = '';
public function getAuthenticationMessage()
{
return $this->_authenticationMessage;
}
public function isAuthenticated()
{
return Zend_Auth::getInstance()->hasIdentity();
}
public function authenticate($username, $password)
{
$doctrineAuthAdapter = new ZendX_Doctrine_Auth_Adapter(
Doctrine_core::getConnectionByTableName('Model_User')
);
$doctrineAuthAdapter->setTableName('Model_User u')
->setIdentityColumn('u.username')
->setCredentialColumn('u.password')
->setIdentity($username)
->setCredential(Model_Utility::encryptPassword($password));
$myAuth = Zend_Auth::getInstance();
$authResult = $myAuth->authenticate($doctrineAuthAdapter);
if(!$authResult->isValid()) {
$this->_authenticationMessage = 'You have entered invalid username and password.';
return false;
} else {
$identity = $doctrineAuthAdapter->getResultRowObject(null, 'password');
$myAuth->getStorage()->write($identity);
return true;
}
}
}
As we can see, the AuthenticationService class is now doing most of the heavy lifting stuff. The controller is left with the duty of checking user login state and dispatching appropriate actions when necessary.
Hope this makes sense, and again more than happy to discuss.
Reference
Related posts:
- ZF authentication using Doctrine
- Application logging with Zend_Log
- Common library files organization in ZF
- ZF, Doctrine and Unit Tests
- Zend Framework 1 and Doctrine 2 integration

I did try to run the code form ZendCasts, it’s not persisting the user identity for me too. But I think it must be an issue to do with the Doctrine setup (I didn’t have time to look into it deep).
The reason why I’m favouring using the ZendX lib is explained in my reply to your comment on the other post.