实用的Zend_ACL + Zend_Auth实施和最佳实践

实用的Zend_ACL + Zend_Auth实施和最佳实践,第1张

实用的Zend_ACL + Zend_Auth实施和最佳实践

我的实现:

问题1

class App_Model_Acl extends Zend_Acl{       const ROLE_GUEST        = 'guest';    const ROLE_USER         = 'user';    const ROLE_PUBLISHER    = 'publisher';    const ROLE_EDITOR       = 'editor';    const ROLE_ADMIN        = 'admin';    const ROLE_GOD          = 'god';    protected static $_instance;        protected function __construct()    {        $this->addRole(new Zend_Acl_Role(self::ROLE_GUEST));        $this->addRole(new Zend_Acl_Role(self::ROLE_USER), self::ROLE_GUEST);        $this->addRole(new Zend_Acl_Role(self::ROLE_PUBLISHER), self::ROLE_USER);        $this->addRole(new Zend_Acl_Role(self::ROLE_EDITOR), self::ROLE_PUBLISHER);        $this->addRole(new Zend_Acl_Role(self::ROLE_ADMIN), self::ROLE_EDITOR);        //unique role for superadmin        $this->addRole(new Zend_Acl_Role(self::ROLE_GOD));        $this->allow(self::ROLE_GOD);                $this->add(new Zend_Acl_Resource('mvc:users'))  ->add(new Zend_Acl_Resource('mvc:users.auth'), 'mvc:users')  ->add(new Zend_Acl_Resource('mvc:users.list'), 'mvc:users');        $this->allow(null, 'mvc:users', array('index', 'list'));        $this->allow('guest', 'mvc:users.auth', array('index', 'login'));        $this->allow('guest', 'mvc:users.list', array('index', 'list'));        $this->deny(array('user'), 'mvc:users.auth', array('login'));                $moduleResource = new Zend_Acl_Resource('mvc:snippets');        $this->add($moduleResource)  ->add(new Zend_Acl_Resource('mvc:snippets.crud'), $moduleResource)  ->add(new Zend_Acl_Resource('mvc:snippets.list'), $moduleResource);        $this->allow(null, $moduleResource, array('index', 'list'));        $this->allow('user', 'mvc:snippets.crud', array('create', 'update', 'delete', 'read', 'list'));        $this->allow('guest', 'mvc:snippets.list', array('index', 'list'));        return $this;    }    protected static $_user;    public static function setUser(Users_Model_User $user = null)    {        if (null === $user) { throw new InvalidArgumentException('$user is null');        }        self::$_user = $user;    }        public static function getInstance()    {        if (null === self::$_instance) { self::$_instance = new self();        }        return self::$_instance;    }    public static function resetInstance()    {        self::$_instance = null;        self::getInstance();    }}class Smapp extends Bootstrap // class Bootstrap extends Zend_Application_Bootstrap_Bootstrap{        protected static $_currentUser;    public function __construct($application)    {        parent::__construct($application);    }    public static function setCurrentUser(Users_Model_User $user)    {        self::$_currentUser = $user;    }        public static function getCurrentUser()    {        if (null === self::$_currentUser) { self::setCurrentUser(Users_Service_User::getUserModel());        }        return self::$_currentUser;    }        public static function getCurrentUserId()    {        $user = self::getCurrentUser();        return $user->getId();    }}

class bootstrap

protected function _initUser(){    $auth = Zend_Auth::getInstance();    if ($auth->hasIdentity()) {        if ($user = Users_Service_User::findoneByOpenId($auth->getIdentity())) { $userLastAccess = strtotime($user->last_access); //update the date of the last login time in 5 minutes if ((time() - $userLastAccess) > 60*5) {     $date = new Zend_Date();     $user->last_access = $date->toString('YYYY-MM-dd HH:mm:ss');     $user->save(); } Smapp::setCurrentUser($user);        }    }    return Smapp::getCurrentUser();}protected function _initAcl(){    $acl = App_Model_Acl::getInstance();    Zend_View_Helper_Navigation_HelperAbstract::setDefaultAcl($acl);    Zend_View_Helper_Navigation_HelperAbstract::setDefaultRole(Smapp::getCurrentUser()->role);    Zend_Registry::set('Zend_Acl', $acl);    return $acl;}

Front_Controller_Plugin

class App_Plugin_Auth extends Zend_Controller_Plugin_Abstract{    private $_identity;        private $_acl;        private $_noacl = array('module' => 'admin',       'controller' => 'error',       'action' => 'no-auth');        private $_noauth = array('module' => 'users',       'controller' => 'auth',       'action' => 'login');        public function preDispatch(Zend_Controller_Request_Abstract $request)    {        $this->_identity = Smapp::getCurrentUser();        $this->_acl = App_Model_Acl::getInstance();        if (!empty($this->_identity)) { $role = $this->_identity->role;        } else { $role = null;        }        $controller = $request->controller;        $module = $request->module;        $controller = $controller;        $action = $request->action;        //go from more specific to less specific        $moduleLevel = 'mvc:'.$module;        $controllerLevel = $moduleLevel . '.' . $controller;        $privelege = $action;        if ($this->_acl->has($controllerLevel)) { $resource = $controllerLevel;        } else { $resource = $moduleLevel;        }        if ($module != 'default' && $controller != 'index') { if ($this->_acl->has($resource) && !$this->_acl->isAllowed($role, $resource, $privelege)) {     if (!$this->_identity) {         $request->setModuleName($this->_noauth['module']);         $request->setControllerName($this->_noauth['controller']);         $request->setActionName($this->_noauth['action']);         //$request->setParam('authPage', 'login');     } else {        $request->setModuleName($this->_noacl['module']);        $request->setControllerName($this->_noacl['controller']);        $request->setActionName($this->_noacl['action']);        //$request->setParam('authPage', 'noauth');    }    throw new Exception('Access denied. ' . $resource . '::' . $role); }        }    }}

和最终-Auth_Controller` :)

class Users_AuthController extends Smapp_Controller_Action {       //sesssion    protected $_storage;    public function getStorage()    {        if (null === $this->_storage) { $this->_storage = new Zend_Session_Namespace(__CLASS__);        }        return $this->_storage;    }    public function indexAction()    {        return $this->_forward('login');    }    public function loginAction()    {$openId = null;        if ($this->getRequest()->isPost() and $openId = ($this->_getParam('openid_identifier', false))) { //do nothing        } elseif (!isset($_GET['openid_mode'])) { return;         }        //$userService = $this->loadService('User');        $userService = new Users_Service_User();        $result = $userService->authenticate($openId, $this->getResponse());        if ($result->isValid()) { $identity = $result->getIdentity(); if (!$identity['Profile']['display_name']) {     return $this->_helper->redirector->gotoSimpleAndExit('update', 'profile'); } $this->_redirect('/');        } else { $this->view->errorMessages = $result->getMessages();        }    }    public function logoutAction()    {        $auth = Zend_Auth::getInstance();        $auth->clearIdentity();        //Zend_Session::destroy();        $this->_redirect('/');    }}

问题2

放在里面

Zend_Auth

成功身份验证后-在存储中写入身份。

$auth->getStorage()->write($result->getIdentity());

identity
-仅仅是
user_id

数据库设计

CREATE TABLE `user` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `open_id` varchar(255) NOT NULL,  `role` varchar(20) NOT NULL,  `last_access` datetime NOT NULL,  `created_at` datetime NOT NULL,  PRIMARY KEY (`id`),  UNIQUE KEY `open_id` (`open_id`)) ENGINE=InnoDB  DEFAULT CHARSET=utf8CREATE TABLE `user_profile` (  `user_id` bigint(20) NOT NULL,  `display_name` varchar(100) DEFAULT NULL,  `email` varchar(100) DEFAULT NULL,  `real_name` varchar(100) DEFAULT NULL,  `website_url` varchar(255) DEFAULT NULL,  `location` varchar(100) DEFAULT NULL,  `birthday` date DEFAULT NULL,  `about_me` text,  `view_count` int(11) NOT NULL DEFAULT '0',  `updated_at` datetime NOT NULL,  PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

一些糖

class Smapp_View_Helper_IsAllowed extends Zend_View_Helper_Abstract{    protected $_acl;    protected $_user;    public function isAllowed($resource = null, $privelege = null)    {        return (bool) $this->getAcl()->isAllowed($this->getUser(), $resource, $privelege);    }        public function getAcl()    {        if (null === $this->_acl) { $this->setAcl(App_Model_Acl::getInstance());        }        return $this->_acl;    }        public function setAcl(Zend_Acl $acl)    {        $this->_acl = $acl;        return $this;    }        public function getUser()    {        if (null === $this->_user) { $this->setUser(Smapp::getCurrentUser());        }        return $this->_user;    }        public function setUser(Users_Model_User $user)    {        $this->_user = $user;        return $this;    }}

对于任何视图脚本中的此类事情

 <?php if ($this->isAllowed('mvc:snippets.crud', 'update')) : ?>    <a title="Edit &laquo;<?=$this->escape($snippetInfo['title'])?>&raquo; snippet">Edit</a> <?php endif?>

有什么问题吗 :)



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5588326.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存