参考Phalcon文档中的INVO实例,以及ACL、Dispatcher、EventsManager说明。
目录结构以Phalcon生成的Simple项目为准,需要在loader.php中加入pluginsDir。
#File:path/app/plugins/Security.php
<?php
use Phalcon\Events\Event,
Phalcon\Mvc\User\Plugin,
Phalcon\Mvc\Dispatcher,
Phalcon\Acl;
/**
* @name 权限安全插件
* @required 需要 ACL|Event|Dispatcher|Session|Flash (视情况修改)
* @author Xiyan <shenqhy#qq.com>
*/
class Security extends Plugin
{
public function __construct($dependencyInjector)
{
$this->_dependencyInjector = $dependencyInjector;
}
private function getAcl()
{
if (!isset($this->persistent->acl))
{
//实例化ACL
$acl = new Phalcon\Acl\Adapter\Memory();
//设置默认权限(禁止)
$acl->setDefaultAction(Phalcon\Acl::DENY);
//添加角色
$roles = array(
'Guests' => new Phalcon\Acl\Role('Guests'),
'Users' => new Phalcon\Acl\Role('Users'),
'Admins' => new Phalcon\Acl\Role('Admins'),
);
foreach ($roles as $role) {
$acl->addRole($role);
}
$AllResources = array(
'GuestsResources' => array(
'index' => array('index','about'),
'signup' => array('index','register'),
'signin' => array('index','login','forgotpwd'),
'api' => array('index','check_invitation_code','check_username_repeat'),
'file' => array('index','download','report'),
),
'UsersResources' => array(
'index' => array('index','about'),
'file' => array('index','download','report'),
'uc' => array('index','upload','fileedit','profile','pedit','files'),
),
'AdminsResources' => array(
'index' => array('index','about'),
'file' => array('index','download','report'),
'xadmin' => array('index','users','allfiles','allreport','banfile'),
),
);
//添加资源并授权对应权限给角色
foreach ($roles as $role) {
foreach ($AllResources[$role->getName().'Resources'] as $resource => $actions) {
$acl->addResource(new Phalcon\Acl\Resource($resource), $actions);
foreach ($actions as $action) {
$acl->allow($role->getName(),$resource,$action);
}
}
}
$this->persistent->acl = $acl;
}
return $this->persistent->acl;
}
public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher)
{
//xdebug_print_function_stack('join beforeDispatch');
$auth = $this->session->get('auth');
if (!$auth){
$role = 'Guests';
} else {
$role = $auth['role'];
}
//获取控制器和动作
$controller = $dispatcher->getControllerName();
$action = $dispatcher->getActionName();
$acl = $this->getAcl();
$allowed = $acl->isAllowed($role, $controller, $action);
if ($allowed != Acl::ALLOW) {
$this->flash->error('无权限访问!');
//在View中勿用{{ flash.output() }}输出,否则会抛出异常,在转发的对应View中使用{{ content() }}可正常输出
$dispatcher->forward(array('controller'=>'index','action'=>'index'));
return false;
}
}
}
/**
* 注意,getAcl中修改角色大小写后
* 需要在beforeExecuteRoute中同步修改以免抛出异常
*/
#File:path/app/config/services.php
/*
* 权限安全插件
*/
$di->set('dispatcher', function() use ($di) {
$eventsManager = $di->getShared('eventsManager');
$security = new Security($di);
/**
* We listen for events in the dispatcher using the Security plugin
*/
$eventsManager->attach('dispatch', $security);
$dispatcher = new Phalcon\Mvc\Dispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
转载请注明:神奇海域 » Phalcon之ACL安全插件