ZF authentication using Doctrine

Edit: There’s a follow up article http://blog.elinkmedia.net.au/2010/01/26/auth-service/

As one of my everyday morning tasks, I just checked the rss feeds from my news reader. Interesting enough, one of my favourite blog authors, Jon Lebensold from ZendCasts, just published a new post on “Writing a Zend_Auth_Adapter with Doctrine“.

The issue that we are trying to solve is to handle user login authentication from an application, which uses Zend Framework and Doctrine ORM. Jon took the approach of writing a custom zend auth adaptor to accomplish the task. I watched the video from ZendCasts, and clearly this is another quality video and it will just work for you.

However here, I want to show you an alternative approach to solve the same problem. I basically used an already written authentication doctrine adapter from the ZendX incubator. The class file can be found here.

To autoload the ZendX_Doctrine_Auth_Adapter class file, obviously you need to include the file in the correct directory inside the “library” directory. So that is “library/ZendX/Doctrine/Auth/Adapter.php”.

Now let’s look at some code. Please note that I am only showing topic-related code here, all other security checking, error checking code have been taken out.

class LoginController extends Zend_Controller_Action
{
    public function loginAction()
    {
        // collect the data from the user
        $loginUsername = $this->getRequest()->getParam('username', '');
        $loginPassword = $this->getRequest()->getParam('password', '');

        $myAuth = Zend_Auth::getInstance();

        // do the authentication
        $authAdapter = $this->_getAuthAdapter($loginUsername, $loginPassword);
        $result = $myAuth->authenticate($authAdapter);
        if (!$result->isValid()) {
            // take care of invalid login
        } else {
            // empty password
            $identity = $authAdapter->getResultRowObject(null, 'password');
            $myAuth->getStorage()->write($identity);

            // all good, do you redirect or whatever
        }
    }

    protected function _getAuthAdapter($username, $password)
    {
        $authAdapter = new ZendX_Doctrine_Auth_Adapter(Doctrine::getConnectionByTableName('Model_User'));

        $encryptedPassword = Model_Utility::encryptPassword($password);

        $authAdapter->setTableName('Model_User u')
            ->setIdentityColumn('u.username')
            ->setCredentialColumn('u.password')
            ->setIdentity($username)
            ->setCredential($encryptedPassword);

        return $authAdapter;
    }

Ok. Most of the code should be pretty self explanatory. The authentication is done with the following assumptions.

  • Your login users are stored in a table called “user”, with at least 2 columns, “username” and “password”.
  • You have your Doctrine “Model_User” class setup.
  • If you store encrypted or hashed passwords in your database (I do), the encryption logic is handled by a static method call from a utility class, “Model_Utility”.

This is it. In our case, we do not need to create an authentication method in “Model_User” as Jon showed us in his video tutorial. The authentication magic is all done by the “ZendX_Doctrine_Auth_Adapter” class.

Hope you find this useful and let me know if you have issues or suggestions.

Reference

Share this article on:
  • Facebook
  • Twitter
  • Google Bookmarks
  • Digg
  • del.icio.us
  • LinkedIn
  • MySpace
  • email
  • Live
  • Reddit
  • RSS
  • StumbleUpon

Related posts:

  1. Authentication service
  2. ZF, Doctrine and Unit Tests
  3. Zend Framework 1 and Doctrine 2 integration
  4. Zend Framework 1 and Doctrine 2 integration – modular setup
  5. Doctrine tricks
Categories: Doctrine - PHP - Zend Framework
 
[...] This post was mentioned on Twitter by Jim Li, Aleksandras S. Aleksandras S said: ZendX_Doctrine_Auth_Adapter so simple and powerful: http://blog.elinkmedia.net.au/2010/01/24/zf-authentication-using-doctrine/ [...]
 
abcphp.com at 22:41 on 25 January 2010
ZF Authentication using Doctrine » elink media blog…

As one of my everyday morning tasks, I just checked the rss feeds from my news reader. Interesting enough, one of my favourite blog authors, Jon Lebensold from ZendCasts, just published a new post on “Writing a Zend_Auth_Adapter with Doctrine“….
 
Authentication Service » elink media blog at 20:22 on 26 January 2010
[...] 26th, 2010 by Jim Li Leave a reply » 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 [...]
Martín
Hi, I followed Jon’s zend cast tutorial and It was fine but if I redirect to another page instead to use forward in the same controller I get an error like this: end_Session::start() – /opt/lampp/htdocs/library_1.9/Zend/Loader.php(Line:164): Error #2 fopen(/opt/lampp/htdocs/transpanish.biz/application/models/AdministradorTable.php) [function.fopen]: failed to open stream: No existe el fichero ó directorio Array
The error is not clear and checking all I discovered that Zend_Auth not maintain data across the pages, when you redirect to another page you can’t check if the user is logon, Zend_Auth loose their data. I couldn’t solve this so I use your approach and it works. I like more this approach because it ’s very similar what I have been using with Zend_Auth_Adapter_DbTable. Do you have the same error using Jon’s approach ? Do you know how to storage Zend_Auth data using Jon’s approach ? Thank you.
2 February 10 at 03:58
@Martín I’ve not tested with Jon’s approach. The reason I like using the ZendX library is that when the integration between ZF and Doctrine becomes mature, there ought to be a dedicated auth adapter developed for Doctrine, just like the adapter for ZendDb. In that case, I’m sort of future proof. I can just replug the adapter with whatever, without having to worry about the details. I’ll give the Zendcasts implementation a try later today and let you know if I have the same issue as you do.
2 February 10 at 09:37
@Martín I just tested the sample app downloaded from ZendCasts. The login identity does NOT persist when I make a redirect to a different controller. However I did not get the error messages you are getting. btw, if you are interested in my solution, you might want to look at the followup post to this one, I did some refactoring to move the auth logic into a service class
2 February 10 at 11:05