我收集到很多如何在Zend Framework控制身份认证的问题。典型的问题是他们不知道如何结合:一个认证适配器 
一个登陆表单 
一个login/logout的controller动作 
检测提交请求的验证用户 
它不是很可怕,但是它需要知道不同MVC块之间如何搭配在一起,和如何使用Zend_Auth。让我们看一下。Authentication Adapter【认证适配器】
为了使这些工作,你需要一个authentication adapter。这个例子不是针对那个的,而是根据文档需要的,你需要给予你的站。我将做一个假设,就是你的认证器需要用户名密码来作为验证凭据。我们的登录controller将用这个适配器,但是简单的需要一个占位符来收回它。
Login Form【登录表单】
登录表单本身非常的简单。你可以创建一些基本的认证规则 使你可以保护数据库或者其他的服务,但是否则保持事情相对简单。为了手册的目的,我们定义了一下标准:用户名只能是字母,在3-20个之间。 
密码必须是数字组成的,在6-20个之间。 
表单如下:
class LoginForm extends Zend_Form
{
public function init()
{
$username = $this->addElement('text', 'username', array(
'filters' => array('StringTrim', 'StringToLower'),
'validators' => array(
'Alpha',
array('StringLength', false, array(3, 20)),
),
'required' => true,
'label' => 'Your username:',
));$password = $this->addElement('password', 'password', array(
'filters' => array('StringTrim'),
'validators' => array(
'Alnum',
array('StringLength', false, array(6, 20)),
),
'required' => true,
'label' => 'Password:',
));$login = $this->addElement('submit', 'login', array(
'required' => false,
'ignore' => true,
'label' => 'Login',
));// We want to display a 'failed authentication' message if necessary;
// we'll do that with the form 'description', so we need to add that
// decorator.
$this->setDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form')),
array('Description', array('placement' => 'prepend')),
'Form'
));
}
}
Login Controller【登录控制】
现在,让我我们创建一个控制器来操纵登录和退出动作。典型的流程如下:用户点击登录表单 
用户提交登录表单 
控制器处理表单 
确认错误,重新显示错误和错误信息。 
成功确认重定向到主页 
已经登录的用户重定向到主页 
退出动作退出用户重定向到登录表单 
这个LoginController将使用你选择的登陆器,既这个登录表单。We will pass to the login form constructor the form action and method (since we now know what they will be for this usage of the form).。当我们获得一个有效值,我们将传递他们到我们的验证器中。创建控制器. 首先, 我们将创建表达那存取和验证适配器.
class LoginController extends Zend_Controller_Action
{
public function getForm()
{
return new LoginForm(array(
'action' => '/login/process',
'method' => 'post',
));
}public function getAuthAdapter(array $params)
{
// Leaving this to the developer...
// Makes the assumption that the constructor takes an array of 
// parameters which it then uses as credentials to verify identity.
// Our form, of course, will just pass the parameters 'username'
// and 'password'.
}
}
其次, 在发送任何动作以前我们需要做以下认证:如果用户已经被验证了,但是没有退出,重定向到主页。 
如果用户没有被认证, 但是已经推出,重定向到登录页面 
下面这个preDispatch()路由将为我们做这些:
class LoginController extends Zend_Controller_Action
{
// ...public function preDispatch()
{
if (Zend_Auth::getInstance()->hasIdentity()) {
// If the user is logged in, we don't want to show the login form;
// however, the logout action should still be available
if ('logout' != $this->getRequest()->getActionName()) {
$this->_helper->redirector('index', 'index');
}
} else {
// If they aren't, they can't logout, so that action should 
// redirect to the login form
if ('logout' == $this->getRequest()->getActionName()) {
$this->_helper->redirector('index');
}
}
}
}
现在,我们需要做我们的登录表单。这是我们最简单的方法--我们简单检索这个表单并且定义到视图。
class LoginController extends Zend_Controller_Action
{
// ...public function indexAction()
{
$this->view->form = $this->getForm();
}
}
Processing the form involves slightly more logic. 我们需要确认我们有一个提交请求 ,然后这个表单是有效的,并且最后这凭据也是有效的。
class LoginController extends Zend_Controller_Action
{
// ...public function processAction()
{
$request = $this->getRequest();// Check if we have a POST request
if (!$request->isPost()) {
return $this->_helper->redirector('index');
}// Get our form and validate it
$form = $this->getForm();
if (!$form->isValid($request->getPost())) {
// Invalid entries
$this->view->form = $form;
return $this->render('index'); // re-render the login form
}// Get our authentication adapter and check credentials
$adapter = $this->getAuthAdapter($form->getValues());
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);
if (!$result->isValid()) {
// Invalid credentials
$form->setDescription('Invalid credentials provided');
$this->view->form = $form;
return $this->render('index'); // re-render the login form
}// We're authenticated! Redirect to the home page
$this->_helper->redirector('index', 'index');
}
}最后,我们可以处理退出动作。这个是登录表单一样;我们简单的清除认证表单确认嘻嘻你,并且重定向。
class LoginController extends Zend_Controller_Action
{
// ...public function logoutAction()
{
Zend_Auth::getInstance()->clearIdentity();
$this->_helper->redirector('index'); // back to login page
}
}Okay, that's it for our login/logout routines. Let's look at the one associated view we have, the form:
<? // login/index.phtml ?>
<h2>Please Login</h2>
<?= $this->form ?>
如上.其实. Zend_Form写脚本很容易.检验登录用户
最后的问题是: 如何确认一个用户是验证的和受限的?如果你仔细看上面preDispatch()方法,你能够看到这个能做什么. Zend_Auth保存认证在session里,允许直接查询:
Zend_Auth::getInstance()->hasIdentity()
你可以用这个确认用户是否已经登录,如果没有可以重定向到登录页.你可以从用户对象中获取身份信息:
$identity = Zend_Auth::getInstance()->getIdentity();
这个可以放到一个helper里来在layout显示登陆状态, 例如:
/**
* ProfileLink helper
*
* Call as $this->profileLink() in your layout script
*/
class My_View_Helper_ProfileLink
{
public $view;public function setView(Zend_View_Interface $view)
{
$this->view = $view;
}public function profileLink()
{
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$username = $auth->getIdentity()->username;
return '<a href="/profile' . $username . '">Welcome, ' . $username . '</a>';
} return '<a href="/login">Login</a>';
}
}