Php Zend_Auth最佳实践

Php Zend_Auth最佳实践,php,zend-framework,authentication,zend-framework-mvc,Php,Zend Framework,Authentication,Zend Framework Mvc,我的目标是要求登录某些页面。我正在使用Zend Framework MVC,并试图找到有关最佳实践的示例 关于我正在寻找的内容的一些注释: 我希望未登录的用户获得一个登录框,然后在验证后返回到页面的登录版本 我想使用依赖注入,避免单例 代码占用空间小-与Zend mvc结构结合 登录框应该是一个单独的控制器,并且头重定向吗?验证成功后如何返回登录页?简单地调用login controller操作以在登录页中显示登录框,或者这是搜索引擎索引的一个缺点 能够使用外部库处理cookie 或者完全不

我的目标是要求登录某些页面。我正在使用Zend Framework MVC,并试图找到有关最佳实践的示例

关于我正在寻找的内容的一些注释:

  • 我希望未登录的用户获得一个登录框,然后在验证后返回到页面的登录版本
  • 我想使用依赖注入,避免单例
  • 代码占用空间小-与Zend mvc结构结合
  • 登录框应该是一个单独的控制器,并且头重定向吗?验证成功后如何返回登录页?简单地调用login controller操作以在登录页中显示登录框,或者这是搜索引擎索引的一个缺点
  • 能够使用外部库处理cookie
或者完全不同的东西。我对Zend框架还相当陌生,我想用“正确的方式”来实现它

  • 我希望未登录的用户获得一个登录框,然后返回到登录框 在页面的版本中,一次 认证
使用并重定向或转发到您的登录

  • 我想使用依赖注入,避免单例
Zend Framework目前不提供任何DI系统,但是,Zend_应用程序_资源_*实际上取代了它。你需要什么样的依赖关系

  • 代码占用空间小-与Zend mvc结构结合
这取决于你

  • 登录框应该是一个单独的控制器,并且头重定向吗?怎么 验证后返回登录页的步骤 成功?一个简单地称之为 登录控制器操作以显示 登录页面中的登录框,或 这是搜索的一个缺点 引擎索引
我主要使用一个特殊的
AuthController
LogoutAction
。为了将用户重定向到试图查看的页面,我总是在表单中添加一个
returnUrl
元素,并注入请求URL的值,以便能够重定向用户,如果没有,我将他重定向到索引/仪表板,具体视情况而定

  • 能够使用外部库处理cookie
Zend_Auth允许您设置您的权限,因此只需实现接口即可

$auth = Zend_Auth::getInstance();
$auth->setStorage(new My_Auth_Storage());
但是永远不要将身份验证结果存储在cookie中,修改和访问您的网站非常容易


您也可以查看我的一个。

不确定这是否是最佳实践,但如果我要实现您的目标,那么我将执行以下操作:

  • 使用唯一可识别的提交按钮创建一个
    LoginForm
    (稍后解释)
  • 使用方法
    getLoginForm
    login
    logout
    和一个或全部方法创建一个
    AuthService
    hasIdentity
    ,以及类似方法
  • 创建具有此服务实例的viewhelper,并根据
    hasIdentity
    的结果,在需要此功能的视图中呈现LoginForm或登录用户的标识
  • 创建一个前端控制器插件,该插件也有一个服务实例,并实现
    preDispatch
    插件挂钩。给它一些要探测的动作的配置。如果
    AuthService->hasIdentity()
    返回true,则不执行任何操作。如果请求是post请求,请查找唯一可识别的提交按钮名称,即:
    $request->getPost('loginSubmitButton',null)默认为
    null
    (如果不可用)。如果不是
    null
    则对服务执行
    登录($request->getPost())
    。如果成功,则重定向到同一操作;如果失败,则跳转并再次在viewhelper中呈现表单(自动显示错误)

  • viewhelper和front controller插件都可以获取该服务,一些服务定位器可以通过在引导程序中将服务注册到
    ServiceStract
    来执行类似于
    ServiceStract::getService('Auth')
    的操作。

    您可以使用和的组合。为了扩展其他答案,我给出了一个简短的示例,说明如何使用zend framework管理身份验证:

    首先,您需要设置一个插件,用于predispatch所有请求,并检查是否允许客户端访问某些数据。此插件可能看起来像这样:

    class Plugin_AccessCheck extends Zend_Controller_Plugin_Abstract {
    
        private $_acl = null;
    
        public function __construct(Zend_Acl $acl) {
            $this->_acl = $acl;
        }
    
        public function preDispatch(Zend_Controller_Request_Abstract $request) {
            //get request information
            $module = $request->getModuleName ();
            $resource = $request->getControllerName ();
            $action = $request->getActionName ();
    
            try {
                if(!$this->_acl->isAllowed(Zend_Registry::get('role'), 
                                    $module . ':' . $resource, $action)){
                    $request->setControllerName ('authentication')
                            ->setActionName ('login');
                }
            }catch(Zend_Acl_Exception $e) {
                $request->setControllerName('index')->setActionName ('uups');
            }
        }
    }
    
    因此,每个用户类型都有您在acl库中定义的特定权限。在每个请求中,您都会检查是否允许用户访问资源。如果没有,则重定向到登录页面,否则preDispatch会将用户传递给资源

    在中,定义允许或拒绝访问的角色、资源和权限,例如:

    class Model_LibraryAcl extends Zend_Acl {
        public function __construct() {
    
            $this->addRole(new Zend_Acl_Role('guests'));
            $this->addRole(new Zend_Acl_Role('users'), 'guests');
            $this->addRole(new Zend_Acl_Role('admins'), 'users');                
    
            $this->add(new Zend_Acl_Resource('default'))
                 ->add(new Zend_Acl_Resource('default:authentication'), 'default')
                 ->add(new Zend_Acl_Resource('default:index'), 'default')
                 ->add(new Zend_Acl_Resource('default:error'), 'default');
    
            $this->allow('guests', 'default:authentication', array('login'));
            $this->allow('guests', 'default:error', 'error');
    
            $this->allow('users', 'default:authentication', 'logout');          
        }
    }
    
    然后,您必须在引导文件中设置acl和auth:

        private $_acl = null;
    
        protected function _initAutoload() {
    
           //...your code           
           if (Zend_Auth::getInstance()->hasIdentity()){
            Zend_Registry::set ('role',
                         Zend_Auth::getInstance()->getStorage()
                                                  ->read()
                                                  ->role);
            }else{
                Zend_Registry::set('role', 'guests');
            }
    
            $this->_acl = new Model_LibraryAcl ();
            $fc = Zend_Controller_Front::getInstance ();
            $fc->registerPlugin ( new Plugin_AccessCheck ( $this->_acl ) );
    
            return $modelLoader;
        }
    
    最后,在身份验证控制器中,您必须使用自定义的身份验证适配器,并设置登录和注销操作:

    public function logoutAction() {
        Zend_Auth::getInstance ()->clearIdentity ();
        $this->_redirect ( 'index/index' );
    }
    
    private function getAuthAdapter() {
        $authAdapter = new Zend_Auth_Adapter_DbTable ( 
                            Zend_Db_Table::getDefaultAdapter ());
        $authAdapter->setTableName('users')
                    ->setIdentityColumn('email')
                    ->setCredentialColumn ('password')
                    ->setCredentialTreatment ('SHA1(CONCAT(?,salt))');
    
        return $authAdapter;
    }
    
    在登录操作中,您需要将登录数据传递给执行身份验证的身份验证适配器

    $authAdapter = $this->getAuthAdapter ();
    $authAdapter->setIdentity ( $username )->setCredential ( $password );
    $auth = Zend_Auth::getInstance ();
    $result = $auth->authenticate ( $authAdapter );
    
    if ($result->isValid ()) {
        $identity = $authAdapter->getResultRowObject ();
        if ($identity->approved == 'true') {
            $authStorage = $auth->getStorage ();
            $authStorage->write ( $identity );
            $this->_redirect ( 'index/index' );
        } else {
           $this->_redirect ( 'authentication/login' );
      }
    

    就这些。我建议您在youtube上的zend auth和zend acl上进行此操作。

    关于所需的依赖关系,特别是会话存储处理程序。关于cookie auth-我已经从中实现了设计原则,我希望利用这一点。如果你真的想使用DI,你可以使用Symfony DI,它可以很好地集成在ZF中,但是,如果你只打算将其用于auth,它可能会增加开销。您仍然可以通过使用应用程序资源$this->getInvokeArg('boostrap')->getResource('AuthService')来编写和检索AuthService;或者使用Zend_Registry。如何在没有引用的情况下在https页面上填充“returnUrl”?您可以在Auth Front Controller插件中附加GET参数并重定向到Auth Controller,或者您可以在$会话中设置它,但多个打开的选项卡可能会导致不一致的结果这是最复杂的