2011-12-01 75 views

回答

1

我们使用处理我们身份验证的Controller plugin(在boot.ini配置文件中引导)。它在preDispatch()阶段检查请求的控制器/操作,并匹配ACL对象(可以从DB,配置文件,XML等中取出)。如果用户没有权限访问目标控制器/操作,则会将消息存储在会话中,并且用户将被重定向到另一个页面,以显示访问禁止消息。

如果用户需要进行身份验证才能访问目标控制器/操作,则通过修改请求对象将用户重定向到登录操作。

使用此插件不需要检查每个控制器中的用户认证/ ACL,因此所有“Access”代码都将包含在一个文件“Access Plugin”中。

为了检查用户身份,我们主要使用“Zend_Auth :: getInstance() - > hasIdenity()”的相同方法,但这只是显示用户是否已通过身份验证。 Zend_Auth的'''getIdentity()''方法返回当前用户标识,但同样只是标识而不是更多。但是,如果您需要用户的更多信息,则可以将用户信息存储在会话中。

我们将用户实现为数据模型,因此每个用户都被定义为一个对象。一个用户在登录操作验证后,我们创建相应的用户对象并将其存储在用户会话是这样的:

// This could be a sample code in AuthController/processloginAction() 
// suppose $username is validated before and stores the username 
$user = new Default_Model_User($username); 
// now $user is our user object, suppose $log is a Zend_Log instance 
$log->info("user id '{$user->getId()}' username: '{$user->getUsername()}' logged in"); 
$sess = Zend_Session_Namespace('auth'); 
$sess->user = $user; 

从现在之一,“身份验证”的会话命名空间的$用户属性是包含所有您需要的信息的用户对象,而不仅仅是身份。每当你想检查用户登录(使用Zend_Auth的旁边),你可以检查用户会话该值的可用性:

$sess = Zend_Session_Namespace('auth'); 
if (!isset($sess->user) || !$sess->user) { 
    // user is not logged in, redirect to login page 
} 
$user = $sess->user; 
/*@var $user Default_Model_User*/ 
$email = $user->getEmail(); 

现在我们检查认证,并有机会获得用户信息(电子邮件,电话等)。

0

完全可以这样做,但为了避免重复该代码,您可以将所有控制器从Zend_Controller_Action的子类A中扩展出来。那么这个类中声明的方法

​​

现在,在您的控制器,它是A的子类,你可以简单地做$this->hasIdentity();代替

1

我使用类似于在http://www.hermanradtke.com/blog/more-reliable-authentication-in-zend-framework/在自己的博客赫尔曼瑞克描述的方法的方法。基本上,创建一个控制器插件作为法扎德提到:

class My_Authentication extends Zend_Controller_Plugin_Abstract 
{ 

    private $_whitelist; 

    public function __construct() 
    { 
     $this->_whitelist = array(
      'index/login' 
     ); 
    } 

    public function preDispatch(Zend_Controller_Request_Abstract $request) 
    { 
     $controller = strtolower($request->getControllerName()); 
     $action = strtolower($request->getActionName()); 
     $route = $controller . '/' . $action; 

     if (in_array($route, $this->_whitelist)) { 
      return; 
     } 

     $auth = Zend_Auth::getInstance(); 
     if ($auth->hasIdentity()) { 
      return; 
     } 

     self::setDispatched(false); 
     // handle unauthorized request... 
    } 
} 

,然后注册该插件在你的引导:

public function run() { 
    $front->registerPlugin(new My_Authentication()); 
} 

我一般采取这种方法有点远和Zend_Acl中融入系统中。要做到这一点我会在下面定义的插件:

类My_Acl_Authentication扩展Zend_Controller_Plugin_Abstract {

private $_acl; 

    public function __construct($acl) 
    { 
     $this->_acl = $acl 
    } 

    public function preDispatch(Zend_Controller_Request_Abstract $request) 
    { 
     $controller = strtolower($request->getControllerName()); 
     $action = strtolower($request->getActionName()); 
     $route = $controller . '/' . $action; 

     if (in_array($route, $this->_whitelist)) { 
      return; 
     } 

     $auth = Zend_Auth::getInstance(); 
     $role = 'anonymous'; 
     if ($auth->hasIdentity()) { 
      $role = $auth->getStorage->read()->role; 
     } 

     if ($this->_acl->isAllowed($role, $route)) { 
      return; 
     } 

     self::setDispatched(false); 
     // handle unauthorized request... 
    } 
} 

如果你走这条路线有一些需要做更多的工作,特别是你要设置的ACL,然后您还必须将用户的角色存储在auth存储中。

相关问题