以下のプラグインを導入すればアクセス管理の幅が広がります。
参考
http://qiita.com/eiroh/items/f37a70a35103de6c6a1b
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
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
config/bootstrap.php に追加します。
Plugin::load('Acl', ['bootstrap' => true]);
<?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"); } }
変更していない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']); } }
変更していない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()); }
public function parentNode() { return null; }
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]]; }
$this->addBehavior('Acl.Acl', ['type' => 'requester']);
$this->addBehavior('Acl.Acl', ['type' => 'requester']);
<?= $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() ?>
<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>
vendor\cakephp\acl\src\AclExtras.php
# public $rootNode = 'controllers'; public $rootNode = 'App';
$ bin/cake Migrations.migrations migrate -p Acl
$ bin/cake acl_extras aco_sync