以下のプラグインを導入すればアクセス管理の幅が広がります。 参考 テーブルの作成 †users, groupsテーブルを作成します。
参考 bakeしてプログラム類を自動生成します。 $ bin/cake bake all users $ bin/cake bake all groups プラグインのインストール †composer.jsonに2行追加します。 "require": { "php": ">=5.5.9", "cakephp/cakephp": "3.3.*", "mobiledetect/mobiledetectlib": "2.*", "cakephp/migrations": "~1.0", "cakephp/plugin-installer": "*", "cakephp/acl": "dev-master", "jcpires/cakephp3-aclmanager": "dev-master" }, # /usr/local/bin/composer.phar update 記述の追加 †bootstrap.php †config/bootstrap.php に追加します。 Plugin::load('Acl', ['bootstrap' => true]); AppController.php †<?php namespace App\Controller; use Cake\Controller\Controller; use Cake\Event\Event; use Cake\Controller\ComponentRegistry; use Acl\Controller\Component\AclComponent; class AppController extends Controller { public function beforeFilter(Event $event) { $this->Auth->allow(); } public function initialize() { parent::initialize(); $this->loadComponent('RequestHandler'); $this->loadComponent('Flash'); $this->loadComponent('Acl.Acl'); $this->loadComponent('Auth', [ 'authorize' => 'Controller', 'unauthorizedRedirect' => false, 'authError' => 'アクセス権限がありません', ]); } public function beforeRender(Event $event) { if (!array_key_exists('_serialize', $this->viewVars) && in_array($this->response->type(), ['application/json', 'application/xml']) ) { $this->set('_serialize', true); } } public function isAuthorized($user) { $Collection = new ComponentRegistry(); $acl = new AclComponent($Collection); $controller = $this->request->controller; $action = $this->request->action; return $acl->check(['Users' => ['id' => $user['id']]], "$controller/$action"); } } GroupsController.php †変更していないfunctionは省いています。 <?php namespace App\Controller; use App\Controller\AppController; use Cake\Event\Event; use JcPires\AclManager\Event\PermissionsEditor; class GroupsController extends AppController { public $helpers = [ 'AclManager' => [ 'className' => 'JcPires/AclManager.AclManager' ] ]; public function add() { $group = $this->Groups->newEntity(); if ($this->request->is('post')) { $group = $this->Groups->patchEntity($group, $this->request->data); if ($this->Groups->save($group)) { $this->Flash->success(__('The group has been saved.')); return $this->redirect(['action' => 'index']); } else { $this->Flash->error(__('The group could not be saved. Please, try again.')); } } $this->set(compact('group')); $this->set('_serialize', ['group']); } public function edit($id = null) { $group = $this->Groups->get($id, [ 'contain' => [] ]); $this->loadComponent('JcPires/AclManager.AclManager'); $EditablePerms = $this->AclManager->getFormActions(); if ($this->request->is(['patch', 'post', 'put'])) { $group = $this->Groups->patchEntity($group, $this->request->data); if ($this->Groups->save($group)) { $this->eventManager()->on(new PermissionsEditor()); $perms = new Event('Permissions.editPerms', $this, [ 'Aro' => $group, 'datas' => $this->request->data ]); $this->eventManager()->dispatch($perms); $this->Flash->success(__('The group has been saved.')); return $this->redirect(['action' => 'index']); } else { $this->Flash->error(__('The group could not be saved. Please, try again.')); } } $this->set(compact('group', 'EditablePerms')); $this->set('_serialize', ['group', 'EditablePerms']); } } UsersController.php †変更していないfunctionは省いています。 <?php namespace App\Controller; use App\Controller\AppController; use Cake\Event\Event; class UsersController extends AppController { public function beforeFilter(Event $event) { parent::beforeFilter($event); $this->Auth->allow(['login']); } public function login() { if ($this->request->is('post')) { $user = $this->Auth->identify(); if ($user) { $this->Auth->setUser($user); return $this->redirect($this->Auth->redirectUrl()); } $this->Flash->error(__('Invalid username or password, try again')); } } public function logout() { return $this->redirect($this->Auth->logout()); } Group.php †public function parentNode() { return null; } User.php †use Cake\ORM\TableRegistry; use Cake\Auth\DefaultPasswordHasher; protected function _setPassword($password) { return (new DefaultPasswordHasher)->hash($password); } public function parentNode() { if (!$this->id) { return null; } if (isset($this->group_id)) { $group_id = $this->group_id; } else { $users_table = TableRegistry::get('Users'); $user = $users_table->find('all', ['fields' => ['group_id']])->where(['id' => $this->id])->first(); $group_id = $user->group_id; } if (!$group_id) { return null; } return ['Groups' => ['id' => $group_id]]; } Groups.php †$this->addBehavior('Acl.Acl', ['type' => 'requester']); Users.php †$this->addBehavior('Acl.Acl', ['type' => 'requester']); Groups/edit.ctp †<?= $this->Form->create($group) ?> <fieldset> <legend><?= __('Edit Group') ?></legend> <?php echo $this->Form->input('name'); ?> <?php foreach ($EditablePerms as $Acos) :?> <?php foreach ($Acos as $controllerPath => $actions) :?> <?php if (!empty($actions)) :?> <h4><?= $controllerPath ;?></h4> <?php foreach ($actions as $action) :?> <?php ($this->AclManager->checkGroup($group, $controllerPath.'/'.$action)) ? $val = 1 : $val = 0 ?> <?= $this->Form->label($controllerPath.'/'.$action, $action);?> <?= $this->Form->select($controllerPath.'/'.$action, [0 => 'No', 1 => 'Yes'], ['value' => $val]) ;?> <?php endforeach ;?> <?php endif;?> <?php endforeach ;?> <?php endforeach ;?> </fieldset> <?= $this->Form->button(__('Submit')) ?> <?= $this->Form->end() ?> Users/login.ctp †<div class="users form"> <?= $this->Flash->render('auth') ?> <?= $this->Form->create() ?> <fieldset> <legend><?= __('Please enter your username and password') ?></legend> <?= $this->Form->input('username') ?> <?= $this->Form->input('password') ?> </fieldset> <?= $this->Form->button(__('Login')); ?> <?= $this->Form->end() ?> </div> aclテーブルの作成 †$ bin/cake Migrations.migrations migrate -p Acl Acoデータの作成 †$ bin/cake acl_extras aco_sync $ bin/cake acl create aco controllers App $ bin/cake acl create aco App isAuthorized 確認 $ bin/cake acl view aco グループとユーザーの登録 †グループを登録 †グループの権限設定 †http://localhost/groups/edit/1 ユーザーの登録 †動作確認 †ログアウト †AppController.phpの一部をコメント化 †#$this->Auth->allow(); リダイレクトされることを確認 †http://localhost/ へアクセスすると http://localhost/users/login へリダイレクトされる 他にも設定した権限通りに動作するか確認します。 ControllerやActionを追加した際の更新方法 †$ bin/cake acl_extras aco_update |