• Subscribe to the RSS feed!
  • Subscribe by Email
  • home
  • blog
  • dev
  • Recent Posts

    • Ze Balkanic Tweetup
      • on May 31, 2009
    • Moblin, Linux for netbooks
      • on May 21, 2009
    • Back
      • on
    • Happy birthday, dear magician…
      • on May 10, 2009
    • Wordpress as CMS tutorial
      • on March 14, 2009
    • New blog - Try Open Source
      • on March 11, 2009
    • Online resources for Zend Framework
      • on March 3, 2009
    • pywst - setting up web projects quickly
      • on February 22, 2009
    • Full Circle Magazine
      • on February 8, 2009
    • Trac on Ubuntu
      • on January 27, 2009
  • Recent Comments

    • Jason Gilmore
      • on June 23rd @ 5:04 am
    • slawek
      • on June 11th @ 1:29 am
    • igor
      • on June 7th @ 9:56 pm
    • Swizec
      • on June 1st @ 11:18 pm
    • Robert
      • on June 1st @ 8:12 pm
    • Eniac
      • on June 1st @ 2:17 pm
    • -1-
      • on May 31st @ 11:04 pm
    • Robert
      • on May 31st @ 10:54 pm
    • Swizec
      • on May 31st @ 10:27 pm
    • blackshtef
      • on May 31st @ 8:14 pm
  • Find me on

    • DZone
    • Google Code
    • Google Reader
    • Last.fm
    • StumbleUpon
    • Twitter
    • Vimeo
  • Friends and Blogs

    • Andrew Taylor
    • Andy Sowards
    • Bojan Pejić
    • Eran Galperin
    • Graham Smith
    • Jani Hartikainen
    • Jasper Tandy
    • Matthew Turland
    • Matthew Weier O’Phinney
    • Miff
    • Miloš Ćuković
    • Nebojša Radović
    • Nemanja Avramović
    • Nemanja Tobić
    • Nikola Krajačić
    • Nikola Plejić
    • Pádraic Brady
    • Rob Allen
    • Swizec Teller
    • Vladimir Stanković
    • WeAreJustCreative
    • Željko Stevanović
  • I use

    • 960 Grid System
    • jQuery
    • Notepad++
    • Subversion
    • Trac
    • Vim
    • Zend Framework
  • Tags

    • about
    • php
    • random
    • example
    • framework
    • zend
    • ubuntu
    • site
    • blog
    • introduction
    • wordpress
    • linux
    • apache
    • setup
    • lamp
    • svn
    • open source
    • registration
    • facebook
    • comic
  • Categories

    • Blablabla
    • Development
    • Free time
    • Places on the web
    • Programming
    • Software
  • Photos

    Big awesome coffee mug
    A 20+ year old scotch, in a 4.5l bottle
    A 20+ year old scotch, in a 4.5l bottle
    Coffee and ratluk

  • Archives

    • May 2009
    • March 2009
    • February 2009
    • January 2009
    • December 2008
    • November 2008
    • October 2008
    • September 2008

Login example with Zend_Auth

by Robert Basic on January 5th, 2009

Happy New Year! Hope everyone had a blast for New Year’s Eve and managed to get some rest :) This is my first working day for this year. I’m still kinda lazy and sleepy. And I wanna eat something all the time. Damn you candies!!!

So, here’s what I’m going to do: authenticate an user against a database table using Zend Framework’s Zend_Auth component. It’s really a piece of cake. You can see a working example here: http://robertbasic.com/dev/login/. Feel free to test it and report any misbehavior down in the comments. In the codes below all paths, class names, actions, etc. will be as are in the example, so you probably will need to changed those according to your setup.

Preparation

Because I’m gonna use a database, be sure to have set the default database adapter in the bootstrap file, I have it setup like this:

$config = new Zend_Config_Ini('../application/dev/config/db_config.ini', 'offline');
$registry = Zend_Registry::getInstance();
$registry->set('db_config',$config);
$db_config = Zend_Registry::get('db_config');
$db = Zend_Db::factory($db_config->db);
Zend_Db_Table::setDefaultAdapter($db);

I’ll need it later in the code. The table structure is as follows:

--
-- Table structure for table `zendLogin`
--

CREATE TABLE `zendLogin` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(32) NOT NULL,
  `password` varchar(32) NOT NULL,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

The login controller

The magic happens in the LoginController. It has two actions: indexAction and logoutAction. The indexAction will take care of showing the login form and processing the login process. The logoutAction will just logout the user. You would never figure out that one on your own, right?

Now, let’s get to the fun part — the code:

<?php
class Dev_LoginController extends Zend_Controller_Action
{
    public function indexAction()
    {
        // If we're already logged in, just redirect
        if(Zend_Auth::getInstance()->hasIdentity())
        {
            $this->_redirect('dev/secured/index');
        }

        $request = $this->getRequest();
        $loginForm = $this->getLoginForm();

        $errorMessage = "";

Not much happening here: if the user is already logged in, I don’t want him at the login form, so just redirect him somewhere else; most likely to a home page or a control panel’s index page.

The Zend_Auth implements the Singleton pattern — if you’re not familiar with it read http://framework.zend.com/manual/en/zend.auth.html#zend.auth.introduction and http://www.php.net/manual/en/language.oop5.patterns.php (at php.net scroll down to the example #2).

So, I’m just asking the Zend_Auth does it have an user identity stored in it; the identity gets stored only upon successful log in. I’m also getting the request object. The getLoginForm() is a function that I wrote for assembling the login form and is a part of the LoginController, I’ll show it’s code later.

if($request->isPost())
{
    if($loginForm->isValid($request->getPost()))
    {
        // get the username and password from the form
        $username = $loginForm->getValue('username');
        $password = $loginForm->getValue('password');

This doesn’t needs a lot of explanation: if it’s a post request, it means the form is submitted. If the submitted data is valid, just get the wanted values from the form.

        $dbAdapter = Zend_Db_Table::getDefaultAdapter();
        $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);

        $authAdapter->setTableName('zendLogin')
                    ->setIdentityColumn('username')
                    ->setCredentialColumn('password')
                    ->setCredentialTreatment('MD5(?)');

Here I’m getting the default database adapter, so I know whit which database I’m working with. Then I’m creating an adapter for Zend_Auth, which is used for authentication; the docs give good explanation on the adapter, read it here: http://framework.zend.com/manual/en/zend.auth.html#zend.auth.introduction.adapters.

Next, I’m telling the authentication adapter which table to use from the database, and which columns from that table. Also, I’m telling it how to treat the credentials — the passwords are stored as MD5 hashes, so the submitted passwords will first be MD5ed and then checked.

        // pass to the adapter the submitted username and password
        $authAdapter->setIdentity($username)
                    ->setCredential($password);

        $auth = Zend_Auth::getInstance();
        $result = $auth->authenticate($authAdapter);

I’m passing to the adapter the user submitted username and password, and then trying to authenticate with that username and password.

        // is the user a valid one?
        if($result->isValid())
        {
            // get all info about this user from the login table
            // ommit only the password, we don't need that
            $userInfo = $authAdapter->getResultRowObject(null, 'password');

            // the default storage is a session with namespace Zend_Auth
            $authStorage = $auth->getStorage();
            $authStorage->write($userInfo);

            $this->_redirect('dev/secured/index');
        }

If the user is successfully authenticated, get all information about him from the table (if any), like the real name, E-mail, etc. I’m leaving out the password, I don’t need that. Next I’m getting the Zend_Auth’s default storage and storing in it the user information. In the end I’m redirecting it where I want it.

else
{
    $errorMessage = "Wrong username or password provided. Please try again.";
}
}
}
$this->view->errorMessage = $errorMessage;
$this->view->loginForm = $loginForm;
}

And this is the end of the indexAction. I know I could take the correct message from $result with getMessages(), but I like more this kind of message, where I’m not telling the user which part did he got wrong.

public function logoutAction()
{
    // clear everything - session is cleared also!
    Zend_Auth::getInstance()->clearIdentity();
    $this->_redirect('dev/login/index');
}

This is the logoutAction. I’m clearing the identity from Zend_Auth, which is also clearing all data from the Zend_Auth session namespace. And, of course, redirecting back to the login form.

protected function getLoginForm()
{
    $username = new Zend_Form_Element_Text('username');
    $username->setLabel('Username:')
            ->setRequired(true);

    $password = new Zend_Form_Element_Password('password');
    $password->setLabel('Password:')
            ->setRequired(true);

    $submit = new Zend_Form_Element_Submit('login');
    $submit->setLabel('Login');

    $loginForm = new Zend_Form();
    $loginForm->setAction('/dev/login/index/')
            ->setMethod('post')
            ->addElement($username)
            ->addElement($password)
            ->addElement($submit);

    return $loginForm;
}

As promised, here’s the code for getLoginForm function. That’s the whole LoginController code, not really a rocket science :) Sorry if it’s a bit hard to keep up with the code, I needed it to break it up in smaller pieces…

And here’s the view script for the indexAction.

<h2>Zend_Login example</h2>

<p>
Hello! This is an example of authenticating users with the Zend Framework...
</p>

<p>Please login to proceed.</p>

<?php if($this->errorMessage != ""): ?>
<p class="error"><?= $this->errorMessage; ?></p>
<?php endif; ?>

<?= $this->loginForm; ?>

Other controllers

Couldn’t come up with a better subtitle :(

Here’s an example how to require the user to log in to see the page: in the init() method ask Zend_Auth is the user logged in, and if not redirect him to the login form. This way the user will have to log in to the “whole controller”. Implement the same only to the indexAction, and the user will have to only log in to see the index page; he’ll be able to access another page without logging in.

class Dev_SecuredController extends Zend_Controller_Action
{
    function init()
    {
        // if not logged in, redirect to login form
        if(!Zend_Auth::getInstance()->hasIdentity())
        {
            $this->_redirect('dev/login/index');
        }
    }

    public function indexAction()
    {
        // get the user info from the storage (session)
        $userInfo = Zend_Auth::getInstance()->getStorage()->read();

        $this->view->username = $userInfo->username;
        $this->view->name = $userInfo->name;
        $this->view->email = $userInfo->email;
    }

    public function anotherAction()
    {
    }
}

I’m also reading out the user information from the Zend_Auth’s storage, that I have stored there during the log in process.

So there. A fully working login system, which can be setup in a really short time.

Update: If you want, you can get an example source code from here: zendLogin.zip ~8kB

Happy hacking!

Share this post:
  • Digg
  • description
  • del.icio.us
  • StumbleUpon
  • Facebook
  • Reddit
  • TwitThis
  • Google
  • E-mail this story to a friend!
Tags: authenticate, authentication, example, framework, login, php, zend.
Categories: Development, Programming.
Subscribe to the feed.

Comments: 18

Grab the comments feed

  • Robert Basic’s Blog: Login example with Zend_Auth : WebNetiques

  • January 6th, 2009

[...] Basic has posted an example of the use of the Zend_Auth component of the Zend Framework inside of an example [...]

  • Robert Basic’s Blog: Login example with Zend_Auth : Dragonfly Networks

  • January 6th, 2009

[...] Basic has posted an example of the use of the Zend_Auth component of the Zend Framework inside of an example [...]

  • AndySowards.com :: Web Development Nerdy Daily Links For 1/06/2009 | AndySowards.com :: Professional Web Design, Development, Programming, Hacks, Downloads, Math and being a Web 2.0 Hipster?

  • January 6th, 2009

[...] Login example with Zend_Auth ~ Robert Basic Login example with Zend Framework and Database Usage! Nice! [...]

  • Goran

  • January 7th, 2009

Mogu li znati šta koristiš kao izvor, neku određenu knjigu, tutoriale ili..?

  • Robert

  • January 7th, 2009

Zdravo Gorane!

Kao osnovni izvor koristim zvanicnu dokumentaciju, kao i sam izvorni kod framework-a, i naravno ono sto pronadjem na netu. Iako mnogi smatraju dokumentaciju losom, ja mislim da je ona dobra i da sadrzi dosta informacija, samo je treba razumeti :)

Pozdrav!

  • gsx

  • January 9th, 2009

and what about form validators ?

  • Robert

  • January 9th, 2009

What about them? Form validators are not the subject of this post.

  • Zoe

  • January 31st, 2009

read http://blog.astrumfutura.com/ much?
At least credit him…

  • Tavares Hanks

  • February 11th, 2009

I have a situation. I am trying to create a simple login and logout without using s database. I don’t know much about MySQL, so that is why I am doing it without a database. There is only one username and one password which is the same where the employee will type it in and takes them to the page that is protected and be able to logout from that page. The site is http://www.richlandcountyrecreation.com go under about us and click on employee forms. It brings us the login page, but the password is visible and it still lets you go to the protected page. What and I doing wrong. Can you help me?

  • Robert

  • February 12th, 2009

@Tavares Sorry, but that login hasn’t much to do with Zend_Login.

  • Storing Data to Database Using PHP | Defafe

  • February 20th, 2009

[...] Login example with Zend_Auth (robertbasic.com) [...]

  • Richard Knop

  • February 24th, 2009

Hey Robert, great article!

I’ve been reading through the Zend_Auth documentation (because I was trying to make a simple login system) and couldn’t quite understand how to set the adapter correctly, now I get it :)

It was pretty simple actually.

  • Login Extjs: Confirm Password | Defafe

  • February 27th, 2009

[...] Login example with Zend_Auth (robertbasic.com) [...]

  • Jim

  • March 5th, 2009

First, let me say this is a great review and tutorial. I found it very informative.

But (you knew there was one coming) I believe I did everything correctly as the code-snippets above reflect, but for some crazy reason, simply attempting to instantiate “new Zend_Auth_Adapter_DbTable($dbAdapter)” doesn’t work. No errors, nothing. No matter what’ I’ve tried I can’t get it to work. I do have other database access activities going on elsewhere, so I dont think it has to do with the database portion of the adapter. Am I missing something?

Here’s my code for LogingController

class LoginController extends Zend_Controller_Action
{
public function indexAction()
{
// If we’re already logged in, just redirect
if(Zend_Auth::getInstance()->hasIdentity())
{
$this->_redirect(’index/products’);
}

$request = $this->getRequest();
$loginForm = $this->getLoginForm();

$errorMessage = “”;
if($request->isPost())
{
if($loginForm->isValid($request->getPost()))
{
// get the username and password from the form
$username = $loginForm->getValue(’username’);
$password = $loginForm->getValue(’password’);
$dbAdapter = Zend_Db_Table::getDefaultAdapter();

$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter, ‘USER_MSTR’, ‘USER_ID’, ‘PASSWD’, ‘PASSWORD(?)’);

// pass to the adapter the submitted username and password
$authAdapter->setIdentity($username)
->setCredential($password);

$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
// is the user a valid one?
if($result->isValid())
{
// get all info about this user from the login table
// omit only the password, we don’t need that
$userInfo = $authAdapter->getResultRowObject(null, ‘PASSWD’);

// the default storage is a session with namespace Zend_Auth
$authStorage = $auth->getStorage();
$authStorage->write($userInfo);

$this->_redirect(’index/products’);
}
else
{
$errorMessage = “Wrong username or password provided. Please try again.”;
}

} // not a valid post
} // not a post at all

$this->view->errorMessage = $errorMessage;
$this->view->loginForm = $loginForm;
}

protected function getLoginForm()
{
$username = new Zend_Form_Element_Text(’username’);
$username->setLabel(’Username:’)
->setRequired(true);

$password = new Zend_Form_Element_Password(’password’);
$password->setLabel(’Password:’)
->setRequired(true);

$submit = new Zend_Form_Element_Submit(’login’);
$submit->setLabel(’Login’);

$loginForm = new Zend_Form();
$loginForm->setAction(’/login/index/’)
->setMethod(’post’)
->addElement($username)
->addElement($password)
->addElement($submit);

return $loginForm;
}

public function logoutAction()
{
// clear everything - session is cleared also!
Zend_Auth::getInstance()->clearIdentity();
$this->_redirect(’login/index’);
}
}
?>

Here’s the pertinent section for my bootstrap …

Zend_Loader::loadClass(’Zend_Auth_Adapter_DbTable’);
Zend_Loader::loadClass(’Zend_Auth’);
… database connectivity stuff is here
Zend_Db_Table::setDefaultAdapter(self::$_db);

  • Mark

  • March 6th, 2009

Any chance you could post the sourcecode?
Would be appreciated.

  • Robert

  • March 6th, 2009

@Jim mate, join us up on http://www.zfforums.com/ and post your problem there. It’ll be easier to talk about it :)

@Mark sure thing!

  • Zend_Auth Manage The Authentication With Plugin | dev.as.art - blog

  • April 17th, 2009

[...] Login example with Zend_Auth by Robert Basic [...]

  • Ahmet Topal

  • May 9th, 2009

Yes, i think this one is nice. I’m using Kohana PHP (but it is +/- like Zend, and i can add Zend to Kohana), this looks good, that what i have searched. I will try to learn Zend, and can use this Code. And i will create a regsiter Formular.. This one shouldn’t be so difficult.. Just connect to database and add user..

But how it is with the User and Admin? Database? Oder must Admin have another Page to login?

Leave a Reply

 

Robert Basic © 2008 — 2009
Design & graphics by: Livia Radvanski
Coded by: Robert Basic
Home page last updated on January 3rd, 2009.
Frameworks used: Zend Framework, jQuery, 960 Grid System
Blog is powered by Wordpress
Subscribe: Entries — RSS & Comments — RSS