Demo – Zend Auth and Zend ACL (Part 1)

This is a multipart series that uses ZF to perform robust web based authentication and authorization. In the latter parts, AJAX is injected into the framework.

Create the Zend framework directory structure

image

The usual ‘controllers’, ‘models’ and ‘views’ directories hold the core mvc code. The include is setup to hold libraries that we will create that will be shared across the app (and which do not fit the paradigm of m, v or c).

Only the ‘web’ folder will be exposed via the webserver as a virtual directory. This is for added security.. You do not want any of your business intelligence files accessible via the web. We will let the ZF do all the heavy lifting for us.

Go ahead and setup the virtual directory to point to MyZF\web

image

After this is done, the actual application can be accessed at http://localhost/MyZF

One other preparatory step is to make sure that ALL requests to our application get routed through our bootstrap file – index.php

If you are using IIS, add the required directives to the web.config file in the web folder (.htaccess if you are using apache).

Creating the bootstrapper : The next item is to create an index.php in the web folder that will accept ALL incoming requests, initialize the Zend Framework and route accordingly.

We will start off with a basic configuration and refactor as required:

<?php
require_once ‘Zend/Loader.php’;
Zend_Loader::registerAutoload();

//setup the layout
Zend_Layout::startMvc(array(‘layoutpath’=>’../views/layouts’));
try
{
    //Initialize the front controller
    $controller = Zend_Controller_Front::getInstance();
    $controller->setControllerDirectory(‘../controllers’);
    $controller->throwExceptions(true);

//go
    $controller->dispatch();
}
catch (Exception $ex)
{
    header(‘Content-Type: text/html; charset=utf-8’);
    echo ‘An unexpected error occurred’;
    echo ‘<h2>’.$ex->getMessage().'</h2>’;
}
?>

Note that in order to use the try/catch block, the throwExceptions(true) has to be set. We will remove that in the future once our custom error controller is ready.

I consider the Zend_Layout to be one of the really cool features of the Zend framework. It forces a uniform look and feel throughout your application. And, it is real easy to setup.

Database : We will create and use a table named ‘users’ to perform standard database authentication:

image

The username and password entered on a login form by the user will be checked against the username and password fields in this database. Note that in a production environment you will probably not store the actual password but a hash of it.

Next, create a config.ini settings file to simplify database access from ZF.

[general]
db.adapter=PDO_MYSQL
db.config.host=localhost
db.config.username=root
db.config.password=password
db.config.dbname=myzf

The modified index.php with the database initialization settings changes to:

<?php
require_once ‘Zend/Loader.php’;
Zend_Loader::registerAutoload();

$config = new Zend_Config_Ini(‘../config.ini’,’general’);
$db = Zend_Db::factory($config->db->adapter,$config->db->config->toArray());
Zend_Db_Table::setDefaultAdapter($db);
//setup the layout
Zend_Layout::startMvc(array(‘layoutpath’=>’../views/layouts’));
try
{
    //Initialize the front controller
    $controller = Zend_Controller_Front::getInstance();
    $controller->setControllerDirectory(‘../controllers’);
    $controller->throwExceptions(true);

//go
    $controller->dispatch();
}
catch (Exception $ex)
{
    header(‘Content-Type: text/html; charset=utf-8’);
    echo ‘An unexpected error occurred’;
}
?>

Creating controllers

Controller classes are the building blocks of a ZF application.

Create a base controller which abstracts the common methods for use in all controllers (All our controllers will inherit form BaseController instead of Zend_Controller_Action):

<?php
class BaseController extends Zend_Controller_Action
{
    protected static $db=null;
    protected static $baseUrl=null;
    protected static $authenticated=null;
    function init()
    {
        //store the db connection info for use throughout app..
        if (self::$baseUrl===null)
        {
            self::$db = Zend_Db_Table::getDefaultAdapter()

     }
        if (self::$baseUrl===null)
        {
            self::$baseUrl=Zend_Controller_Front::getInstance()->getBaseUrl();
        }
        $this->view->baseUrl = self::$baseUrl;
      }
}
?>

This class provides a convenient handle to the database, baseurl and authenticated flag. These may potentially be required on every page. The use of static variables is an optimisation measure.

Let us create code that renders the default page (index). The index action in the index controller is the code that is executed when the default page is invoked.

<?php
class IndexController extends BaseController
{
    public function indexAction()
    {
        //do nothing.. display the default index.phtml
    }
}
?>

A really simple index.phtml will work for our purposes:

<h1>Welcome to MyZF</h1>

Now, if you point your browser to http://localhost/myzf, you should see the welcome message on the page.

We are now ready to create a separate controller named AuthController that handles all aspects of user authentication. The shell is as shown below:

<?php class AuthController extends BaseController
{
    public function indexAction()
    {
        $this->_forward(‘login’);
    }
    public function loginAction()
    {
    }
    public function logoutAction()
    {
       Zend_Auth::getInstance()->clearIdentity();
       $this->_redirect(‘/’);
    }
    public function identifyAction()
    {
    }
}
?>

The indexAction simiply forwards the request to the loginAction routine (indexAction is an abstract method and MUST be implemented).  The logout action simply uses the Zend_Auth instance to clear the Identity. The regular login form (/views/scripts/auth/login.phtml) with fields for username and password looks like:

<h1>Login</h1>
<p>Please log in here</p>
<form method="post" action='<?php echo $this->baseUrl?>/auth/identify’>
<div>
<label>Username</label>
<input type="text" name="username" vale=""/>
</div>
<div>
<label>Password</label>
<input tyep="password" name="password" value="" />
</div>
<div>
<input type="submit" name="login" value="Login" />
</div>
</form>

Notice the use of $this->baseUrl… This is available to us in the view because of our base controller class!

If you run the application that has been developed so far at

http://localhost/myzf/auth

You should see the login page (embedded neatly inside your general layout page)

Click here to go over to the next part in this series…

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s