这部分代码有效(简化部分):
class UsersController extends AppController
{
public function initialize(): void
{
parent::initialize();
$this->loadComponent('Flash');
$this->loadComponent('Authentication.Authentication');
}
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
//...
$protectedMethods = ['login', 'logout', 'edit'];
if (!empty($this->request->getAttribute('identity')) &&
in_array($this->request->getAttribute('identity')->get('role'), array_keys(ADMINROLES)) &&
in_array($this->request->getParam('action'), $protectedMethods)) {
$this->Flash->error(__('Invalid username or password'));
$this->Authentication->logout();
return $this->redirect(['controller' => 'Users', 'action' => 'login']);
}
}
}
我想将位于 beforeFilter 内的代码部分转换为组件函数,因为它在许多其他控制器中重复,并简化 PHP 代码如下:
这部分代码不起作用(简化部分):
class UsersController extends AppController
{
public function initialize(): void
{
parent::initialize();
$this->loadComponent('Flash');
$this->loadComponent('Authentication.Authentication');
$this->loadComponent('AuthenticationBlocker');
}
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
...
// Blocking access to protected functions for admins
$this->AuthenticationBlocker->adminRoles(['login', 'logout', 'edit']);
}
}
该组件如下所示:
class AuthenticationBlockerComponent extends Component {
// The other component your component uses
protected array $components = ['Flash', 'Authentication.Authentication'];
public $controller;
public function beforeFilter()
{
$this->controller = $this->getController();
}
public function adminRoles($methods) {
if (!empty($this->getController()->getRequest()->getAttribute('identity')) AND in_array($this->getController()->getRequest()->getAttribute('identity')->get('role'),array_keys(ADMINROLES)) AND in_array($this->getController()->getRequest()->getParam('action'),$methods)){
$this->Flash->error(__('Invalid username or password'));
$this->Authentication->logout();
return $this->controller->redirect(['controller' => 'Users', 'action' => 'login']);
}
}
}
发生错误的代码部分是:$this->Authentication->logout();
<?php
declare(strict_types=1);
namespace App\Controller\Component;
use Cake\Controller\Component;
use Cake\Core\Configure;
class AuthenticationBlockerComponent extends Component {
// The other component your component uses
protected array $components = ['Flash','Authentication.Authentication'];
public $controller;
public function beforeFilter()
{
$this->controller = $this->getController();
}
//Blocking access to administration for admins
public function adminRoles(array $methods): void {
$identity = $this->getController()->getRequest()->getAttribute('identity');
$action = $this->getController()->getRequest()->getParam('action');
// Check if user is logged in and has admin role and if the action is in allowed methods
if ($identity AND in_array($identity->get('role'), array_keys(ADMINROLES)) AND in_array($action, $methods)) {
$this->controller->Flash->error(__('Invalid username or password'));
$this->controller->Authentication->logout();
$this->controller->redirect(['controller' => 'Users', 'action' => 'login']);
}
}
}