[[CakePHP3めも]] #contents 以下のプラグインを導入すればアクセス管理の幅が広がります。 -[[CakePhp3-AclManager:https://github.com/JcPires/CakePhp3-AclManager]] -[[acl:https://github.com/cakephp/acl]] 参考~ http://qiita.com/eiroh/items/f37a70a35103de6c6a1b *テーブルの作成 [#d0c29a9e] users, groupsテーブルを作成します。 参考~ http://book.cakephp.org/2.0/ja/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html#id1 bakeしてプログラム類を自動生成します。 $ bin/cake bake all users $ bin/cake bake all groups *プラグインのインストール [#g641d913] 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 *記述の追加 [#h760fadf] **bootstrap.php [#t1ec03b4] config/bootstrap.php に追加します。 Plugin::load('Acl', ['bootstrap' => true]); **AppController.php [#n74de87f] <?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 [#e57f02bd] 変更していない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 [#v1c27b25] 変更していない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 [#y50f5d87] public function parentNode() { return null; } **User.php [#f5d3bc5c] 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 [#c3c3a5c3] $this->addBehavior('Acl.Acl', ['type' => 'requester']); **Users.php [#z63e0b65] $this->addBehavior('Acl.Acl', ['type' => 'requester']); **Groups/edit.ctp [#z53145a2] <?= $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, 'App/'.$controllerPath.'/'.$action)) ? $val = 1 : $val = 0 ?> <?= $this->Form->label('App/'.$controllerPath.'/'.$action, $action);?> <?= $this->Form->select('App/'.$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 [#wb7cec0e] <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> **AclExtras.php [#y9aa2b27] vendor\cakephp\acl\src\AclExtras.php # public $rootNode = 'controllers'; public $rootNode = 'App'; *aclテーブルの作成 [#fefb1003] $ bin/cake Migrations.migrations migrate -p Acl *Acoデータの作成 [#webad04c] $ bin/cake acl_extras aco_sync