|
以下のプラグインを導入すればアクセス管理の幅が広がります。 参考 テーブルの作成†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 |