使用cakephp 1.2中新增的访问控制组件(acl)

时间:2022-05-30 08:08:19

Reference:
 
https://www6.software.ibm.com/developerworks/cn/education/opensource/os-php-cake2/section5.html
 http://groups.google.ch/group/cake-php/msg/891b850d908f667a

IBM文章使用的是1.1.x的版本,对于cake_1.2.0.5146alpha 不适用了.
这里是cake_1.2.0.5146alpha的用法:

1. 初始化Acl数据库表
 cake acl initdb
2. 定义ARO

下面的代码是作为action的一部分实现的.

 定义ARO组

    $aro = $this->Acl->Aro;
    
$aro->create(array
 (
        
'model' => 'User',

        
'parent_id'=>1, # parent_id 为父类aco的id号,整个Acos表模拟的一棵树结构,访问树上特定节点类似与XML的xpath表达式,例如"/users/hezhiqiang"
        'foreign_key' => $this->User->id,
        
'alias' => $this->data['User']['username']
    ));

    
// 保存模型

    $aro->save();
# 表aros和acos结构是一样的,其中的列名称含义有几个目前还没有搞清楚

3. 创建ACO

 

    // 取得aco对象,Aco继承自AppModel,所以具有一般Model的所有功能
    $aco = $this->Acl->Aco;
    
// 调用create方法创建aco,参数是一个数组,其中的数组键对应数据库表acos中的列名称

    $aco->create(array (
        
'foreign_key' => 0,

        
'alias' => 'modules'
    ));
    
// 保存到数据库
    $aco->save();

 表aros和acos结构是一样的,其中的列名称含义有几个目前还没有搞清楚

4. 添加Acl记录 (关联Aco和Aro,控制有那些权限)

使用cakephp 1.2中新增的访问控制组件(acl)    // (只读)
使用cakephp 1.2中新增的访问控制组件(acl)
    $this->Acl->allow($this->data['User']['username'],$this->params['controller'],'read');
使用cakephp 1.2中新增的访问控制组件(acl)    
// (创建,读,更新,删除)

使用cakephp 1.2中新增的访问控制组件(acl)
    $this->Acl->allow($this->data['User']['username'],$this->params['controller'],'*');
使用cakephp 1.2中新增的访问控制组件(acl)
使用cakephp 1.2中新增的访问控制组件(acl)    
$this->Acl->deny()的使用和allow一样.但是含义不同

表aros_acos的结构

使用cakephp 1.2中新增的访问控制组件(acl)

5. 一个完整注册用户的方法,并默认地之只授予用户读权限

    function add() {
        
$this->set('username_error', 'username must be between 6 and 40 characters.'
);
        
if (!empty ($this->
data)) {
            
if ($this->User->
validates()) {
                
if ($this->User->findByUsername($this->data['User']['username'])) { // if a user exists

                    $this->User->invalidate('username', '用户已经存在了,请换一个名字.');
                } 
else
 {

                    
# hash the user's password

                    $this->data['User']['password'= md5($this->data['User']['password']);
                    
if ($this->User->save($this->
data)) {

                        
# get the aro object, typically this is a user

                        $aro = $this->Acl->Aro;

                        
# 创建一个Aro对象

                        $aro->create(array (
                            
'model' => 'User',                      # 与模型关联

                            'parent_id'=>1,                         # 父Aro对象ID,一般是一个组.比如users,如果是根节点.不需要设置parent_id,删除此行
                            'foreign_key' => $this->User->id, # 目前不清楚,待细细研究
                            'alias' => $this->data['User']['username'# aro别名,这里是用户名
                        ));

                        
// save to model

                        $aro->save();
/*

            #modules 由我手动创建.aco要有个专门的controller进行管理,放在这里为了更简单的说明如何创建aco

                        $aco = $this->Acl->Aco;
            # 模块ACO,包括网站的各个部分,一般作为根节点
                        $aco->create(array (
                            'foreign_key' => 0,
                            'alias' => 'modules'
                        ));
                        $aco->save(); # 数据库生成一条id为1的记录.

                        $aco->create(array (
                            'parent_id' => 1, # 父节点的id号
                            'foreign_key' => 0, # 目前不清楚,待细细研究
                            'alias' => $this->params['controller'] # 一个Aco对象的别名,一般设置为控制器名称
                        ));
                        $aco->save();
*/

            
# allow方法:allow($aro,$aco,$action)
            # $aro,$aco的意思就不用说了,这里主要是$action,可用的值在aros_acos表中的最后4个列的名称,不包括'_',或者$action = '*'
            # 可取的值为: create,read,update,delete和*

            
# set only read for user $this->data['User']['username']
                        $this->Acl->allow($this->data['User']['username'],$this->params['controller'],'read');

            
# set all privilieges for user $this->data['User']['username']

            # $this->Acl->allow($this->data['User']['username'], $this->params['controller'], '*');

                        
# store the usename to session
                        $this->Session->write('user', $this->data['User']['username']);

                        
# query by username to get user info

                        $results = $this->User->findByUsername($this->data['User']['username']);

                        
# update login time

                        $results['User']['updated'= date("Y-m-d H:i:s");

                        
# save to session

                        $this->Session->write('updated', $results['User']['updated']);

                        
# save to db

                        $this->User->save($results);

                        
# jump to the user index page

                        $this->redirect('/users/index');
                    } 
else
 {
                        
$this->flash('There was a problem saving this information', '/users/add'
);
                    }
                }
            } 
else
 {
                
$this->validateErrors($this->
User);
            }
        }
        
# debug

        $this->Session->write('data', $this->data);
        
$this->Session->write('params', $this->
params);
    }

    6. 授权用户才有权访问knownusers,这是通过$this->Acl->check()方法判断的.

    function knownusers() {
    
# check($aro, $aco, $action)

    # 检查$aro对$aco是否有$action权限
        if ($this->Acl->check($this->Session->read('user'), 'users', 'read')) {
            
$this->set('knownusers', $this->User->findAll(null, array
 (
                
'id',

                
'username',
                
'first_name',
                
'last_name',
                
'email',
                
'created',
                
'updated'
            )
, 'id DESC'));
        } 
else
 {
            
$this->Session->setFlash('你无权查看产品信息,可能是你没有注册或则是权限不够.'
);
        }
    }

OK,到这里基本的Acl认证过程就完成了.花了我两三天的工夫啊