Can anyone help me understand the deal with Cakephp 3.3 and a BeforeFilter/Auth Redirect issue I'm experiencing.
I'm using the default Auth component. I've created a custom component that additionally checks for a session variable (Registration), and if that variable is not set redirects to a page designed to make a selection to set the desired Registration.
Here's my custom component:
<?php
namespace App\Controller\Component;
use Cake\Controller\Component;
use Cake\Network\Request;
class RegistrationCheckComponent extends Component
{
private $_allowedActions = [];
private $_superUserBypass = false;
public $components = ['Auth'];
public function superUserBypass($val = false) {
$this->_superUserBypass = $val;
}
public function allow(Array $allowedActions = []) {
$this->_allowedActions = $allowedActions;
}
public function verify() {
if($this->_superUserBypass) {
return true;
}
$session = $this->request->session();
//if Auth Registration is not set
if(!$session->read('Auth.Registration')) {
//if requested action is not in the array of allowed actions, redirect to select registration
if(!in_array($this->request->param('action'), $this->_allowedActions)) {
return $this->redirect();
};
return true;
}
return true;
}
public function redirect() {
$controller = $this->_registry->getController();
return $controller->redirect($this->config('redirect'));
}
}
Not all controller's require the Registration variable to be set, that's why I decided to go with the component approach. The component is however loaded in the AppController by this line:
$this->loadComponent('RegistrationCheck', ['redirect' => ['controller' => 'Users', 'action' => 'registrations']]);
In the controllers that require the Registration variable to be set, I include the following beforeFilter function:
public function beforeFilter(Event $event) {
parent::beforeFilter($event);
return $this->RegistrationCheck->verify();
}
Now, I've had some Integration Tests defined, here's one of them:
public function testUnauthenticatedEdit()
{
$this->get('/teams/edit');
$this->assertRedirect(['controller' => 'Users', 'action' => 'login']);
}
So, after I implemented my RegistrationCheck component, I ran the Integration Tests. I was expecting the test to pass, it did not. The interesting thing is that it actually returned a redirect to Users->registrations rather than Users->login as I had expected.
It looks to me that the RegistrationCheck redirect is happening before the Auth component redirect. I'm not sure it's a huge deal, because a redirect to registrations without Auth set is going to end up redirecting back to login, but it seems incorrect to ignore it...also, I'd just like to understand a bit more of what is actually going on.
Can anyone suggest changes to my code that would ensure the Auth component is handled before the RegistrationCheck component?
Thanks in advance.
Well, after a little more research, I found the answer I'm looking for here: http://book.cakephp.org/3.0/en/controllers/components/authentication.html#deciding-when-to-run-authentication
Pretty simple really, just wanted to include an answer here for anyone who may stumble across the same question.