php 需要指导以开始使用 Zend ACL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/545702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 23:02:55  来源:igfitidea点击:

Need guidance to start with Zend ACL

phpzend-frameworkauthenticationuser-controlsacl

提问by Udders

I am currently working on a site that requires ACL and as I am using Zend, it makes sense for me to make use of their ACL class but I have little to zero idea of how to do this. I have read the docs but it confused me further...basically all I want to do is to set up two user groups e.g. "normal" and "admin", normal users can access all pages that have a controller that is not admin while admin can obviously access the admin controller pages.

我目前正在一个需要 ACL 的站点上工作,并且当我使用 Zend 时,使用他们的 ACL 类对我来说是有意义的,但我对如何做到这一点几乎没有想法。我已经阅读了文档,但它让我更加困惑......基本上我想要做的就是设置两个用户组,例如“普通”和“管理员”,普通用户可以访问所有具有非管理员控制器的页面,而admin 显然可以访问管理控制器页面。

I have many questions:

我有很多问题:

  1. How do I set this up?
  2. Should I run it through a DB or the config.ini?
  3. Where do I place my ACL.php?
  4. How do I write such a script?
  5. How do I then call, is this done in the Index?.
  1. 我该如何设置?
  2. 我应该通过 DB 还是 config.ini 运行它?
  3. 我在哪里放置我的 ACL.php?
  4. 我如何编写这样的脚本?
  5. 然后我如何调用,这是在索引中完成的吗?。

I would very much appreciate if you guide me to a website or a good tutorial.

如果您指导我访问网站或好的教程,我将不胜感激。

回答by Marek Janouch

I implemented similar thing not so long ago. Basic concept follows in an example code.

不久前我实施了类似的事情。示例代码中遵循基本概念。

I created my own configAcl.php file which is loaded in bootstrap file, in my case it is index.php. Here is how it'd be according to your case:

我创建了自己的 configAcl.php 文件,该文件加载到引导程序文件中,在我的例子中它是 index.php。根据您的情况,情况如下:

$acl = new Zend_Acl();

$roles  = array('admin', 'normal');

// Controller script names. You have to add all of them if credential check
// is global to your application.
$controllers = array('auth', 'index', 'news', 'admin');

foreach ($roles as $role) {
    $acl->addRole(new Zend_Acl_Role($role));
}
foreach ($controllers as $controller) {
    $acl->add(new Zend_Acl_Resource($controller));
}

// Here comes credential definiton for admin user.
$acl->allow('admin'); // Has access to everything.

// Here comes credential definition for normal user.
$acl->allow('normal'); // Has access to everything...
$acl->deny('normal', 'admin'); // ... except the admin controller.

// Finally I store whole ACL definition to registry for use
// in AuthPlugin plugin.
$registry = Zend_Registry::getInstance();
$registry->set('acl', $acl);

Another case is if you want to allow normal user only "list" action on all your controllers. It's pretty simple, you'd add line like this:

另一种情况是,如果您想在所有控制器上仅允许普通用户“列出”操作。这很简单,你可以添加这样的行:

$acl->allow('normal', null, 'list'); // Has access to all controller list actions.

Next you should create new plugin which takes care of credential checking automatically when there is a request for some controller action. This checking takes place in preDispatch() method that is called before every call to the controller action.

接下来,您应该创建新的插件,当有一些控制器动作的请求时,它会自动处理凭证检查。此检查发生在每次调用控制器操作之前调用的 preDispatch() 方法中。

Here is AuthPlugin.php:

这是 AuthPlugin.php:

class AuthPlugin extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $loginController = 'auth';
        $loginAction     = 'login';

        $auth = Zend_Auth::getInstance();

        // If user is not logged in and is not requesting login page
        // - redirect to login page.
        if (!$auth->hasIdentity()
                && $request->getControllerName() != $loginController
                && $request->getActionName()     != $loginAction) {

            $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector');
            $redirector->gotoSimpleAndExit($loginAction, $loginController);
        }

        // User is logged in or on login page.

        if ($auth->hasIdentity()) {
            // Is logged in
            // Let's check the credential
            $registry = Zend_Registry::getInstance();
            $acl = $registry->get('acl');
            $identity = $auth->getIdentity();
            // role is a column in the user table (database)
            $isAllowed = $acl->isAllowed($identity->role,
                                         $request->getControllerName(),
                                         $request->getActionName());
            if (!$isAllowed) {
                $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector');
                $redirector->gotoUrlAndExit('/');
            }
        }
    }
}

Final steps are loading your configAcl.php and register the AuthPlugin in bootstrap file (probably index.php).

最后一步是加载您的 configAcl.php 并在引导程序文件(可能是 index.php)中注册 AuthPlugin。

require_once '../application/configAcl.php';

$frontController = Zend_Controller_Front::getInstance();
$frontController->registerPlugin(new AuthPlugin());

So this is the basic concept. I didn't test the code above (copy and paste and rewrite just for the showcase purpose) so it's not bullet-proof. Just to give an idea.

所以这是基本概念。我没有测试上面的代码(复制、粘贴和重写只是为了展示目的)所以它不是防弹的。只是给一个想法。

EDIT

编辑

For the clarity. The code above in AuthPlugin suppose that the $identity object is filled with user data ("role" column in the database). This could be done within the login process like this:

为了清楚起见。AuthPlugin 中的上述代码假设 $identity 对象填充了用户数据(数据库中的“角色”列)。这可以在登录过程中完成,如下所示:

[...]
$authAdapter = new Zend_Auth_Adapter_DbTable($db);
$authAdapter->setTableName('Users');
$authAdapter->setIdentityColumn('username');
$authAdapter->setCredentialColumn('password');
$authAdapter->setIdentity($username);
$authAdapter->setCredential(sha1($password));
$authAdapter->setCredentialTreatment('? AND active = 1');
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) {
    $data = $authAdapter->getResultRowObject(null, 'password'); // without password
    $auth->getStorage()->write($data);
[...]

回答by axiom82

This solution may prove to be the simplest implementation of Zend_Acl.

这个解决方案可能被证明是 Zend_Acl 的最简单的实现。

Example:

例子:

class UserController extends Zend_Controller_Action {

    public function preDispatch(){

        $resource = 'user_area';
        $privilege = $this->_request->getActionName();
        if (!$this->_helper->acl($resource, $privilege)) $this->_redirect();

    }

}

Zend/Controller/Action/Helper/Acl.php

Zend/Controller/Action/Helper/Acl.php

class Zend_Controller_Action_Helper_Acl extends Zend_Controller_Action_Helper_Abstract {

    protected $acl;
    protected $role;

    protected function getAcl(){

        if (is_null($this->acl)){

            $acl = new Zend_Acl();

            $acl->addResource(new Zend_Acl_Resource('user_area'));
            $acl->addResource(new Zend_Acl_Resource('customer_area'), 'user_area');
            $acl->addResource(new Zend_Acl_Resource('web_area'));

            $acl->addRole(new Zend_Acl_Role('guest'));      
            $acl->addRole(new Zend_Acl_Role('user'), 'guest');

            $acl->allow('guest', 'web_area');
            $acl->allow('guest', 'user_area', array(
                'forgot-password',
                'login'
            ));
            $acl->allow('user', 'user_area');
            $acl->allow('customer', 'customer_area');

            $this->acl = $acl;

        }

        return $this->acl;

    }

    protected function getRole(){

        if (is_null($this->role)){

            $session = new Zend_Session_Namespace('session');
            $role = (isset($session->userType)) ? $session->userType : 'guest';
            $this->role = $role;

        }

        return $this->role;

    }

    public function direct($resource, $privilege = null){

        $acl = $this->getAcl();
        $role = $this->getRole();
        $allowed = $acl->isAllowed($role, $resource, $privilege);
        return $allowed;

    }

}

回答by Saurabh Chandra Patel

Play with This structure . get role and resource from database and save this in session for or any caching . enter image description here

玩这个结构。从数据库中获取角色和资源并将其保存在会话或任何缓存中。在此处输入图片说明