トップページ > CakePHP > CakePHP 10.2 ACL 開発例の補足

CakePHP 10.2 ACL 開発例の補足

  • 2009-02-12 (木) 8:30

CakePHPのオンラインドキュメントには、親切な開発例が2つ掲載されており、基本的な開発手順を学ぶ助けとなります。
しかし、「10.2 ACL を制御するシンプルなアプリケーション」では、手順が若干省略されているために分かりにくい個所がいくつかあります。
ここでは、学習の手助けとなる補足情報を記載しておきます。

10.2.1 アプリケーションの準備
この章では、bakeを利用した各テーブルに対するモデル、コントローラ、ビューの作成手順が省略されています。
以下に、bakeを利用したモデル、コントローラ、ビューの作成手順を記載します。(bakeでappディレクトリの初期設定が行われている事が前提)

1. bakeを起動すると、コマンドの一覧が表示されます。

$ cd (appディレクトリ)
$ cake bake
Welcome to CakePHP v1.2.1.8004 Console
---------------------------------------------------------------
App : (app名)
Path: (appディレクトリ)
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[ D]atabase Configuration
[ M]odel
[ V]iew
[ C]ontroller
[ P]roject
[ Q]uit
What would you like to Bake? (D/M/V/C/P/Q)

2. モデルを作成するためMを選択すると、データベースの一覧が表示されます。最初にGroupのモデルを作成するために1を選択し、対話形式で設定を行います。
Would you like to supply validation criteria for the fields in your model? (y/n)
でyを選択すると、一部のフィールドでvalidation optionsの選択を要求されますが、全て初期設定のままリターンキーで問題ありません。
Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)? (y/n)
はnを選択し、
Cake test suite not installed. Do you want to bake unit test files anyway? (y/n)
はyを選択します。
一通り設定が終わると初期画面に戻りますので、Groupと同様の手順でPost、User、Widgetのモデルを作成していきます。

> M
---------------------------------------------------------------
Bake Model
Path: (appディレクトリ)/models/
---------------------------------------------------------------
Possible Models based on your current database:
1. Group
2. Post
3. User
4. Widget
Enter a number from the list above, type in the name of another model, or 'q' to exit
[q] > 1
Would you like to supply validation criteria for the fields in your model? (y/n)
[y] > 

Field: id
Type: integer
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
1 - alphaNumeric
2 - between
3 - blank
.
.
27 - url
28 - userDefined
29 - Do not do any validation on this field.
... or enter in a valid regex validation string.

[29] >
.
.
Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)? (y/n)
[y] > n

---------------------------------------------------------------
The following Model will be created:
---------------------------------------------------------------
Name:       Group
Validation: Array
(
    [name] => notempty
)

Associations:
---------------------------------------------------------------
Look okay? (y/n)
[y] > y

Baking model class for Group...

Creating file (appディレクトリ)/models/group.php
Wrote (appディレクトリ)/models/group.php
Cake test suite not installed.  Do you want to bake unit test files anyway? (y/n)
[y] > 

You can download the Cake test suite from http://cakeforge.org/projects/testsuite/

Baking test fixture for Group...

Creating file (appディレクトリ)/tests/fixtures/group_fixture.php
Wrote (appディレクトリ)/tests/fixtures/group_fixture.php

Baking unit test for Group...

Creating file (appディレクトリ)/tests/cases/models/group.test.php
Wrote (appディレクトリ)/tests/cases/models/group.test.php

3. 次にコントローラを作成するためCを選択します。モデルと同様に、Group、Post、User、Widgetに対して処理を行います。
ほとんどは初期設定のままリターンキーで問題ありませんが、
Would you like to use scaffolding? (y/n)
はnを、
Would you like to include some basic class methods (index(), add(), view(), edit())? (y/n)
はyを選択します。

> C
---------------------------------------------------------------
Bake Controller
Path: (appディレクトリ)/controllers/
---------------------------------------------------------------
Possible Controllers based on your current database:
1. Groups
2. Posts
3. Users
4. Widgets
Enter a number from the list above, type in the name of another controller, or 'q' to exit
[q] > 1
---------------------------------------------------------------
Baking GroupsController
---------------------------------------------------------------
Would you like to build your controller interactively? (y/n)
[y] >
Would you like to use scaffolding? (y/n)
[n] > n
Would you like to include some basic class methods (index(), add(), view(), edit())? (y/n)
[n] > y
Would you like to create the methods for admin routing? (y/n)
[n] >
Would you like this controller to use other helpers besides HtmlHelper and FormHelper? (y/n)
[n] >
Would you like this controller to use any components? (y/n)
[n] >
Would you like to use Sessions? (y/n)
[y] > 

---------------------------------------------------------------
The following controller will be created:
---------------------------------------------------------------
Controller Name:  Groups
---------------------------------------------------------------
Look okay? (y/n)
[y] >  

Creating file (appディレクトリ)/controllers/groups_controller.php
Wrote (appディレクトリ)/controllers/groups_controller.php
Cake test suite not installed.  Do you want to bake unit test files anyway? (y/n)
[y] > 

You can download the Cake test suite from http://cakeforge.org/projects/testsuite/

Baking unit test for Groups...

Creating file (appディレクトリ)/tests/cases/controllers/groups_controller.test.php
Wrote (appディレクトリ)/tests/cases/controllers/groups_controller.test.php

4. 最後にビューを作成するためVを選択します。他と同様に、Group、Post、User、Widgetに対して処理を行います。
Would you like to create some scaffolded views (index, add, view, edit) for this controller?
NOTE: Before doing so, you’ll need to create your controller and model classes (including associated models). (y/n)
はyを
Would you like to create the views for admin routing? (y/n)
はnを選択します。

> V
---------------------------------------------------------------
Bake View
Path: (appディレクトリ)/views/
---------------------------------------------------------------
Possible Controllers based on your current database:
1. Groups
2. Posts
3. Users
4. Widgets
Enter a number from the list above, type in the name of another controller, or 'q' to exit
[q] > 1
Would you like to create some scaffolded views (index, add, view, edit) for this controller?
NOTE: Before doing so, you'll need to create your controller and model classes (including associated models). (y/n)
[n] > y
Would you like to create the views for admin routing? (y/n)
[y] > n

Creating file (appディレクトリ)/views/groups/index.ctp
Wrote (appディレクトリ)/views/groups/index.ctp

Creating file (appディレクトリ)/views/groups/view.ctp
Wrote (appディレクトリ)/views/groups/view.ctp

Creating file (appディレクトリ)/views/groups/add.ctp
Wrote (appディレクトリ)/views/groups/add.ctp

Creating file (appディレクトリ)/views/groups/edit.ctp
Wrote (appディレクトリ)/views/groups/edit.ctp
---------------------------------------------------------------

View Scaffolding Complete.

10.2.2 Auth を追加する準備

10.2.3 ACL のデータベーステーブルの初期化

10.2.4 リクエスタとして振舞う
後半にグループの追加について記載がありますが、こちらはWebブラウザで
http://(アプリケーションURL)/groups/add
にアクセスし、グループを作成することを指しています。
ユーザの追加についても同様で、
http://(アプリケーションURL)/users/add
でユーザを作成することを指しています。Groupの欄には、グループのidを指定します。

10.2.5 ACO の作成
ここでは、controllersという名のトップレベルのACOの作成手順が解説してありますが、作成方法として
・コマンドラインから作成する方法
・プログラムの中にACL作成用のコードを一時的に作成し、一度だけ実行後にコードを削除する方法
の2種類が解説されています。前者の方法を選ぶのが素直に思います。
尚、AuthComponent に根ノードの存在を教えるコードは、AppControllerクラスのbeforeFilter()メソッドの最後に追加します。

PHP
function beforeFilter() {
    // AuthComponent のコンフィギュレーション
    $this->Auth->authorize = 'actions';
    $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
    $this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
    $this->Auth->loginRedirect = array('controller' => 'posts', 'action' => 'add');

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

10.2.6 ACO の作成を自動化するツール
ここでは、前ページで作成した controllers ACOの下に、app/controllers ディレクトリ内に準備した全てのコントローラ、及びアクションのACOを自動作成する手順が記載されています。
AppControllerクラスに、buildAcl()メソッドを作成し、beforeFilter()メソッドの最後にbuildAcl()を呼び出すコードを記述するのが素直かと思います。

PHP
function beforeFilter() {
    // AuthComponent のコンフィギュレーション
    $this->Auth->authorize = 'actions';
    $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
    $this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
    $this->Auth->loginRedirect = array('controller' => 'posts', 'action' => 'add');

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

    $this->buildAcl();
}

ブラウザで、
http://(アプリケーションURL)/users
等に一回アクセスしACOの作成が確認できたら、AppControllerクラスからbuildAcl()メソッドと、beforeFilter()メソッド内のbuildAcl()の呼び出し行を削除します。
最後にAuthComponentを無効化するコードの除去の記述がありますが、これは、GroupsController、UsersControllerクラスとに追加したbeforeFilter()メソッド内の
$this->Auth->allowedActions = array(’*');
の行の削除を指しますが、これは後で行います。

10.2.7 パーミッションの設定
最初にコマンドラインからパーミッションを設定する方法が記載されていますが、これはコマンド利用方法の解説であり、そのまま実行しても機能しません。
ここでも、やはり一時的なコードを使ってパーミッションを設定します。UsersControllerクラスにinitDB()メソッドを追加し、beforeFilter()メソッドの最後にinitDB()の呼び出し行を追加します。

PHP
function beforeFilter() {
    parent::beforeFilter();
    $this->Auth->allowedActions = array('*');
    $this->initDB();
}

尚、initDB()メソッドですが、次のように修正しておく必要があります。

PHP
function initDB() {
    //$group =& $this->User->Group;
    App::import('Model', 'Group');
    $group = new Group();

    // 管理者グループには全てを許可する
    $group->id = 1;
    $this->Acl->allow($group, 'controllers');

    // マネージャグループには posts と widgets に対するアクセスを許可する
    $group->id = 2;
    $this->Acl->deny($group, 'controllers');
    $this->Acl->allow($group, 'controllers/Posts');
    $this->Acl->allow($group, 'controllers/Widgets');
    $this->Acl->allow($group, 'controllers/Users/logout');

    // ユーザグループには posts と widgets に対する追加と編集を許可する
    $group->id = 3;
    $this->Acl->deny($group, 'controllers');
    $this->Acl->allow($group, 'controllers/Posts/add');
    $this->Acl->allow($group, 'controllers/Posts/edit');
    $this->Acl->allow($group, 'controllers/Widgets/add');
    $this->Acl->allow($group, 'controllers/Widgets/edit');
    $this->Acl->allow($group, 'controllers/Users/logout');
}

先頭部分は、$this->User->GroupがNULLであるためにエラーが発生する問題の対応です。
あと、マネージャグループ、ユーザグループのユーザでログインするとログアウトできない問題があったため、それぞれallowパーミッションを追加しています。

ブラウザで、
http://(アプリケーションURL)/users
等に一回アクセスしパーミッションの作成が確認できたら、UsersControllerクラスからinitDB()メソッドと、beforeFilter()メソッド内のinitDB()の呼び出し行を削除します。併せて、GroupsController、UsersControllerクラスのbeforeFilter()メソッドから
$this->Auth->allowedActions = array(’*');
の行を削除します。

PHP
function beforeFilter() {
    parent::beforeFilter();
    //$this->Auth->allowedActions = array('*');
    //$this->initDB();
}

10.2.8 ログイン

10.2.9 ログアウト

10.2.10 最後に

トップページ > CakePHP > CakePHP 10.2 ACL 開発例の補足

お知らせ

トップページへ戻る