4

I'm working on my first user login in Zend Framework, but I'm a little confused with Zend_Auth. All the articles I read about it use it directly in the controller. But to me, it makes more sense, to work as a plugin What do you guys think?

drew010
  • 68,777
  • 11
  • 134
  • 162
aattia
  • 39
  • 1
  • 3

2 Answers2

3

You can use it as a plugin, the only downside is that if you initialize the plugin in your bootstrap, then the plugin will be executed for every controller and action, since it would have to run before your controller.

You could extend Zend_Auth and add extra methods to set up the auth adapter and manage the storage, and then you can just call Your_Custom_Auth::getInstance() to get the auth instance and then you can check for auth in the preDispatcth() part of your controllers that need auth.

This way you can easily work with zend_auth in multiple places with less code

<?php

class My_User_Authenticator extends Zend_Auth
{
    protected function __construct()
    {}

    protected function __clone()
    {}

    public static function getInstance()
    {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    // example using zend_db_adapter_dbtable and mysql
    public static function getAdapter($username, $password)
    {
        $db = Zend_Controller_Front::getInstance()
                                     ->getParam('bootstrap')
                                     ->getResource('db');

        $authAdapter = new Zend_Auth_Adapter_DbTable($db,
                                                     'accounts',
                                                     'username',
                                                     'password');

        $authAdapter->setIdentity($username)
                    ->setCredential($password)
                    ->setCredentialTreatment(
                        'SHA1(?)'
                    );

        return $authAdapter;
    }

    public static function updateStorage($storageObject)
    {
        self::$_instance->getStorage()->write($storageObject);
    }
}


// in your controllers that should be fully protected, or specific actions
// you could put this in your controller's preDispatch() method
if (My_User_Authenticator::getInstance()->hasIdentity() == false) {
    // forward to login action
}


// to log someone in
$auth = My_User_Authenticator::getInstance();

$result = $auth->authenticate(
    My_User_Authenticator::getAdapter(
        $form->getValue('username'),
        $form->getValue('password'))
);

if ($result->isValid()) {
    $storage = new My_Session_Object();
    $storage->username = $form->getValue('username');
    // this object should hold the info about the logged in user, e.g. account details
    My_User_Authenticator::getInstance()->updateStorage($storage); // session now has identity of $storage
    // forward to page
} else {
    // invalid user or pass
}

Hope that helps.

drew010
  • 68,777
  • 11
  • 134
  • 162
  • To extend on my answer, I have created a plugin that uses a class similar to that above for my admin area, since i want to protect every admin page. The plugin hooks preDispatch() and gets an instance of My_Admin_Auth and if there is no identity and the controller is not login, then it forwards to the login form. this way I cannot accidentally forget to protect a controller in the admin module. – drew010 Sep 18 '11 at 07:17
  • Don't get confused between Authentication and Authorization(and ACL) (see [Wikipedia Article](http://en.wikipedia.org/wiki/Authentication#Authentication_vs._authorization)) – adlawson Sep 18 '11 at 22:54
1

"Plugin" in ZF doesn't only mean "front controller plugin", also Action helpers, view helpers...

ZF guru Matthew Weier O'Phinney wrote an excellent article about creating action helpers, and guess what ?..

He illustrates it with an Auth widget !

http://weierophinney.net/matthew/archives/246-Using-Action-Helpers-To-Implement-Re-Usable-Widgets.html

don't forget to read the articles comments, as a lot of interesting Q&A are handled there

Frederik Eychenié
  • 1,253
  • 7
  • 8