phalcon——访问控制列表ACL
一个完整的使用实例(将acl封装成一个插件使用):
use Phalcon\Acl; use Phalcon\Acl\Role; use Phalcon\Acl\Resource; use Phalcon\Events\Event; use Phalcon\Mvc\User\Plugin; use Phalcon\Mvc\Dispatcher; use Phalcon\Acl\Adapter\Memory as AclList; class SecurityPlugin extends Plugin { //返回一个已存在的或新创建的acl列表 public function getAcl() { if(!isset($this->persistent->acl)) { $acl = new AclList(); //设置默认访问级别为“拒绝” $acl->setDefaultAction(Acl::DENY); //添加角色 $roles = array( 'users' => new Role('Users'), 'guests' => new Role('Guests') ); foreach($roles as $role) { $acl->addRole($role); } //添加私有资源 $privateResources = array( 'posts' => array('post'), 'comments' => array('comment') ); foreach($privateResources as $resource => $actions) { $acl->addResource(new Resource($resource),$actions); } //添加公有资源 $publicResources = array( 'index' => array('index'), 'register' => array('index'), 'login' => array('index','start','end'), 'posts' => array('index','detail') ); foreach($publicResources as $resource => $actions) { $acl->addResource(new Resource($resource),$actions); } //公有资源访问控制 foreach($roles as $role) { foreach($publicResources as $resource => $actions) { foreach($actions as $action) { $acl->allow($role->getName(),$resource,$action); } } } //私有资源访问控制 foreach($privateResources as $resource => $actions) { foreach($actions as $action) { $acl->allow('Users',$resource,$action); } } $this->persistent->acl = $acl; } return $this->persistent->acl; } //查询acl列表进行权限控制 public function beforeDispatch(Event $event,Dispatcher $dispatcher) { $auth = $this->session->get('auth'); if(!$auth) { //查询当前用户的身份 $role = 'Guests'; } else { $role = 'Users'; } $controller = $dispatcher->getControllerName(); $action = $dispatcher->getActionName(); $acl = $this->getAcl(); $allowed = $acl->isAllowed($role,$controller,$action); if($allowed != Acl::ALLOW) { //需要用户登录才有权限 $dispatcher->forward(array( 'controller' => 'login', 'action' => 'index' )); $this->session->destroy(); return false; } } } 在注入调度控制器时绑定到一个事件控制器中: $di->set('dispatcher',function() use ($di) { $eventsManager = new EventsManager; $eventsManager->attach('dispatch:beforeDispatch',new SecurityPlugin); $dispatcher = new Dispatcher; $dispatcher->setEventsManager($eventsManager); return $dispatcher; });
这样每次从一个方法跳转到另一个方法之前程序都会先去查询一下权限控制列表,看看用户对即将跳转的方法是否有访问权限,若没有权限则跳转到插件中指定的方法。
此外,还可以使用继承机制来构造更复杂的角色,只需要在添加角色的函数的第二个参数中写上要继承的那个角色的实例即可:
// 创建角色
$roleAdmins = new Role("Administrators", "Super-User role");
$roleGuests = new Role("Guests");
// 添加 "Guests" 到 ACL
$acl->addRole($roleGuests);
// 使Administrators继承Guests的访问权限
$acl->addRole($roleAdmins, $roleGuests);
为了提高性能, Phalcon\Acl 的实例可以被实例化到APC, session, 文本或数据库中:
// 保存实例化的数据到文本文件中
file_put_contents("app/security/acl.data", serialize($acl));
// 返序列化
$acl = unserialize(file_get_contents("app/security/acl.data"));
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)