CakePHP ACL Pluginを使ってみる

notoです。

CakePHPでACL(アクセスコントロールリスト)を利用する際に、管理するのがやたら億劫でしたので、ACL Pluginを利用してみました。

環境

  • CakePHP 1.3.12
  • ACL Plugin1.0.7

SQL

UserモデルとRoleモデルを作成するためのSQLを発行します。 DB名は「codelife」としておきます。自身の環境に合わせて変更してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE  TABLE IF NOT EXISTS `codelife`.`users` (
  `id` INT(20) UNSIGNED NOT NULL AUTO_INCREMENT ,
  `role_id` INT(11) UNSIGNED NOT NULL ,
  `username` VARCHAR(60) NOT NULL ,
  `password` VARCHAR(64) NOT NULL ,
  `created` DATETIME NULL DEFAULT NULL ,
  `modified` DATETIME NULL DEFAULT NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `codelife`.`roles` (
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT ,
  `title` VARCHAR(20) NOT NULL ,
  `alias` VARCHAR(20) NOT NULL ,
  `created` DATETIME NULL DEFAULT NULL ,
  `modified` DATETIME NULL DEFAULT NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;

ACLを利用するためのSQLを発行します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
CREATE  TABLE IF NOT EXISTS `codelife`.`aros` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
  `parent_id` INT(10) NULL ,
  `model` VARCHAR(255) NULL ,
  `foreign_key` INT(10) NULL ,
  `alias` VARCHAR(255) NULL ,
  `lft` INT(10) NULL ,
  `rght` INT(10) NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `codelife`.`aros_acos` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
  `aro_id` INT(10) NOT NULL ,
  `aco_id` INT(10) NOT NULL ,
  `_create` VARCHAR(2) NOT NULL ,
  `_read` VARCHAR(2) NOT NULL ,
  `_update` VARCHAR(2) NOT NULL ,
  `_delete` VARCHAR(2) NOT NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS `codelife`.`acos` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
  `parent_id` INT(10) NULL ,
  `model` VARCHAR(255) NULL ,
  `foreign_key` INT(10) NULL ,
  `alias` VARCHAR(255) NULL ,
  `lft` INT(10) NULL ,
  `rght` INT(10) NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;

RolesテーブルにAdminとMemberを追加します。

1
2
3
INSERT INTO `codelife`.`roles` (`id`, `title`, `alias`, `created`, `modified`) VALUES
('1', 'Admin', 'admin', '2011-10-11 00:00:00', '2011-10-11 00:00:00'),
('2', 'Member', 'member', '2011-10-11 00:00:00', '2011-10-11 00:00:00');

Model

ACLを利用する為に、UserモデルとRoleモデルにparentNode関数を記述してあげます。 この辺りはCakePHPのマニュアルと同様です。

user.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php

class User extends AppModel {

    /**
     * モデル名
     */
    public $name = 'User';

    /**
     * Behaviors
     */
    public $actsAs = array('Acl' =>; array('type' => 'requester'));

    /**
    * belongsTo
    */
    public $belongsTo = array('Role');

    public function parentNode() {
        if (!$this->id && empty($this->data)) {
            return null;
        }
        $data = $this->data;
        if (empty($this->data)) {
            $data = $this->read();
        }
        if (!$data['User']['role_id']) {
            return null;
        } else {
            return array('Role' => array('id' => $data['User']['role_id']));
        }
    }
}
role.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

class Role extends AppModel {

    /**
     * モデル名
     */
    public $name = 'Role';

    /**
     * Behaviors
     */
    public $actsAs = array('Acl' => array('type' => 'requester'));

    /**
    * hasMany
    */
    var $hasMany = array(
                    'User' => array(
                        'className'  => 'User',
                        'conditions' => '',
                        'foreignKey' => 'role_id',
                        'dependent'  => false
                    )
    );

    public function parentNode() {
        return null;
    }
}

Authコンポーネント設定

app_controller.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * コンポーネント
 */
var $components = array('Acl', 'Auth');

/**
 * beforeFilter
 */
public function beforeFilter(){

    $this->Auth->actionPath = 'controllers/';

    $this->Auth->authorize = 'actions';
}

core.php設定

コメントアウトがされていないことを確認します。

config/core.php
1
2
Configure::write('Acl.classname', 'DbAcl');
Configure::write('Acl.database', 'default');

ユーザー作成

アプリケーション内からユーザーを作成します。arosテーブルにユーザーが追加されていることを確認してください。

ACL Plugin

ACL Plugin aclフォルダを「/app/plugins」に配置します。

bootstrap設定

ACL Plugin内のbootstrapを以下のように設定します。

plugins/acl/config/bootstrap.php
1
2
3
4
5
6
7
8
9
10
11
Configure :: write('acl.aro.role.model', 'Role');

Configure :: write('acl.aro.role.primary_key', 'id');

Configure :: write('acl.aro.role.foreign_key', 'role_id');

Configure :: write('acl.aro.user.model', 'User');

Configure :: write('acl.aro.user.primary_key', 'id');

Configure :: write('acl.aro.role.display_field', 'title');

設定し終わったら、「/app/config/bootstrap.php」に先ほど設定したファイルをincludeします。

1
require_once(APP . DS . 'plugins' . DS . 'acl' . DS . 'config' . DS . 'bootstrap.php');

core.php設定

コメントアウトされていないことを確認します。

config/core.php
1
Configure::write('Routing.prefixes', array('admin'));

http://localhost/admin/aclでアクセスできるようroutes.phpを設定します。

routes.php設定

config/routes.php
1
Router::connect('/admin', array('controller' => 'acl', 'action' => 'index', 'admin' => true));

http://localhost/admin/aclにアクセスしてACL設定ページが表示されることを確認します。

あとはbuild Actions ACO Build missing AROs 等ゴニョゴニョしたらいいと思います。 手順のみで説明がほぼなくてすいません。。。

Comments