CodeIgniter与Zend Acl结合实现轻量级权限控制
Tag:CodeIgniter Zend Acl权限控制
1、Zend_Acl简介
Zend_Acl为权限管理提供轻量并灵活的访问控制列表(ACL,access control list)的实现。一般地,应用软件可以利用这样的功能限制某些特定对象来访问特定保护的对象。
resource(资源)是一个限制访问的对象。在Zend_Acl中,创建一个resource非常简单。Zend_Acl提供了resource接口Zend_Acl_Resource_Interface使开发者在程序中创建resources非常容易。
role(角色)是一个可以发出请求去访问Resource的对象。像Resources一样,创建一个role也非常简单。Zend_Acl提供了Zend_Acl_Role_Interface使开发者创建roles非常容易。
通过规范和访问控制列表(ACL)的使用,应用软件可以控制角色(roles)如何来访问资源(resources)。
2、CodeIgniter设置
解压ZendAcl目录,放置在system/libraries/中如下图所示:

其中包含Acl.php和Excetion.php两个必须文件,以及Acl权限控制文件。当然,修改文件包含为绝对路径。例如:Acl.php中的包含文件修改为:
require_onceBASEPATH.'/libraries/zend/Acl/Resource/Interface.php';
require_onceBASEPATH.'/libraries/zend/Acl/role.php';
require_onceBASEPATH.'/libraries/zend/Acl/Resource.php';
下面我们在application/libraries/中写下我们自己的library—Acl.php
<?phpif( ! defined('BASEPATH'))exit('No direct script access allowed');
/*
* library Acl
* @auth Liuguoqing
* date 20091225
* Using the Zend Framework ACL Library in Codeigniter
* Acl.php
* $roles:角色
* $resources:资源
* $permissions:权限
*/
require_onceBASEPATH .'libraries/zend/Acl.php';
classCI_AclextendsZend_Acl {
/*
*初始化Acl
*/
function__construct() {
$CI= &get_instance();
$this->acl =newZend_Acl();
//获取角色
$CI->db->order_by('ParentId','ASC');
$query=$CI->db->get('cw_roles');
$roles=$query->result();
//获取资源
$CI->db->order_by('parentId','ASC');
$query=$CI->db->get('cw_resources');
$resources=$query->result();
//获取权限
$query=$CI->db->get('cw_permissions');
$permissions=$query->result();
//Add the roles to the ACL
foreach($rolesas$roles) {
$role=newZend_Acl_Role($roles->id);
$roles->parentId != null ?
$this->acl->addRole($role,$roles->parentId):
$this->acl->addRole($role);
}
//Add the resources to the ACL
foreach($resourcesas$resources) {
$resource=newZend_Acl_Resource($resources->id);
$resources->parentId != null ?
$this->acl->add($resource,$resources->parentId):
$this->acl->add($resource);
}
//Add the permissions to the ACL
foreach($permissionsas$perms) {
$perms->read =='1'?
$this->acl->allow($perms->role,$perms->resource,'read') :
$this->acl->deny($perms->role,$perms->resource,'read');
$perms->write =='1'?
$this->acl->allow($perms->role,$perms->resource,'write') :
$this->acl->deny($perms->role,$perms->resource,'write');
$perms->modify =='1'?
$this->acl->allow($perms->role,$perms->resource,'modify') :
$this->acl->deny($perms->role,$perms->resource,'modify');
$perms->publish =='1'?
$this->acl->allow($perms->role,$perms->resource,'publish') :
$this->acl->deny($perms->role,$perms->resource,'publish');
$perms->delete =='1'?
$this->acl->allow($perms->role,$perms->resource,'delete') :
$this->acl->deny($perms->role,$perms->resource,'delete');
}
//Change this to whatever id your adminstrators group is
//管理员默认拥有所有权限
$this->acl->allow('1');
}
/*
* Methods to query the ACL.
*/
functioncan_read($role,$resource) {
return$this->acl->isAllowed($role,$resource,'read')?TRUE:FALSE;
}
functioncan_write($role,$resource) {
return$this->acl->isAllowed($role,$resource,'write')?TRUE:FALSE;
}
functioncan_modify($role,$resource) {
return$this->acl->isAllowed($role,$resource,'modify')?TRUE:FALSE;
}
functioncan_delete($role,$resource) {
return$this->acl->isAllowed($role,$resource,'delete')?TRUE:FALSE;
}
functioncan_publish($role,$resource) {
return$this->acl->isAllowed($role,$resource,'publish')?TRUE:FALSE;
}
}
至此,我们就可以在controller中加载自己的类库实现权限控制了。但是我们发现还是不很方便,为此我们可以再添加一个zendacl_helper:
<?phpif( ! defined('BASEPATH'))exit('No direct script access allowed');
/**
* ZendAcl Helper
*
* Contains shortcuts to well used Userlib functions
* Using the Zend Framework ACL Library in Codeigniter
* @package CentWare
* @subpackage Helpers
* @author Liu Guoqing
* @copyright Copyright (c) 2010
* @license
* @link
* @filesource
*/
// ---------------------------------------------------------------------------
/*
*
* check_acl
* check_acl权限控制设置
* $resource资源
* $action 动作
* @author Liuguoqing
*/
if( ! function_exists('check_acl'))
{
functioncheck_acl($resource,$action=NULL)
{
$CI= & get_instance();
$role=$CI->session->userdata('Roelid');
if($action=='read'){
return$CI->acl->can_read($role,$resource);
}
if($action=='add'){
return$CI->acl->can_write($role,$resource);
}
if($action=='modify'){
return$CI->acl->can_modify($role,$resource);
}
if($action=='delete'){
return$CI->acl->can_delete($role,$resource);
}
if($action=='publish'){
return$CI->acl->can_publish($role,$resource);
}
return FALSE;
}
}
/* End of file zendacl_helper.php */
/* Location: ./helpers/zendacl_helper.php */
总结:ZendAcl用于控制权限角色非常方便……如有不明之处请与本人联系。
QQ:603031225 DJBLOG:http://hi.baidu.com/850317
3、服数据库结构表:
SQl:--
--表的结构`ci_sessions`
--
CREATE TABLE IF NOT EXISTS `ci_sessions` (
`session_id` varchar(40) character set latin1 NOT NULL default '0',
`ip_address` varchar(16) character set latin1 NOT NULL default '0',
`user_agent` varchar(50) character set latin1 NOT NULL,
`user_data` text NOT NULL,
`last_activity` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`session_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
--表的结构`cw_permissions`
--
CREATE TABLE IF NOT EXISTS `cw_permissions` (
`id` int(11) NOT NULL auto_increment,
`role` int(11) default NULL COMMENT '角色',
`resource` int(11) default NULL COMMENT '资源',
`read` tinyint(1) default '0',
`write` tinyint(1) default '0',
`modify` tinyint(1) default '0',
`delete` tinyint(1) default '0',
`publish` tinyint(1) default '0',
`description` varchar(255) collate utf8_bin default NULL COMMENT '描述',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;
--
--表的结构`cw_resources`
--
CREATE TABLE IF NOT EXISTS `cw_resources` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) collate utf8_bin default NULL COMMENT '名称',
`description` varchar(255) collate utf8_bin default NULL COMMENT '描述',
`parentId` int(11) default NULL COMMENT '父类ID',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;
--
--表的结构`cw_roles`
--
CREATE TABLE IF NOT EXISTS `cw_roles` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) collate utf8_bin NOT NULL,
`description` varchar(255) collate utf8_bin default NULL,
`date` datetime NOT NULL COMMENT '日期',
`parentId` int(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;
--
--表的结构`cw_users`
--
CREATE TABLE IF NOT EXISTS `cw_users` (
`id` int(10) unsigned NOT NULL auto_increment,
`username` varchar(32) NOT NULL,
`password` varchar(40) NOT NULL,
`email` varchar(254) NOT NULL,
`active` tinyint(1) unsigned NOT NULL default '0',
`roles` int(10) unsigned default NULL,
`activation_key` varchar(32) default NULL,
`last_visit` timestamp NULL default CURRENT_TIMESTAMP,
`created` datetime NOT NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`),
KEY `password` (`password`),
KEY `group` (`roles`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;