Question

Anonymous user is hitting the following URL that requires authenticated user: /myprofile/settings. I would like to be able to abort MVC dispatch loop and send user to sign-in location.

The code:

$evt = $di->getShared('dispatcher')->getEventsManager();
$evt->attach('dispatch', new AccessControl\Security($di));

Security class:

/**
 * This action is executed before execute any action in the application
 */
public function beforeDispatch(Event $event, Dispatcher $dispatcher)
{
    // User is not authenticated, access should be denied.
    $this->response->redirect('/signin');
}

The question. How do I tell the dispatcher to skip routing to myprofile Controller & settings Action and instead dump the response (which will redirect to /signin).

$event->stop() did not work.

Thanks!

Was it helpful?

Solution

Here's the solution:

public function beforeDispatch(Event $event, Dispatcher $dispatcher)
{
    // User is not authenticated, access should be denied.
    $this->response->redirect('/signin');

    //Returning "false" we tell to the dispatcher to stop the current operation
    return false;
}

http://docs.phalconphp.com/en/latest/reference/tutorial-invo.html for more information.

OTHER TIPS

To avoid the extra roundtrip redirect involves, you could also just dispath the request to your login action.

This code is taken from an heavily customized app so it might not work out of the box for you but you'll get the idea (it also adds the requested url as a dispatcher param so you can output it in a hidden field of your login form and redirect the user on successful login):

public function beforeDispatchLoop(Event $event, Dispatcher $dispatcher)
{
    if (! $this->auth->hasIdentity() && ! $this->auth->authenticateViaRememberMe()) {
        $dispatcher->setModuleName('login');
        $dispatcher->setControllerName('Login');
        $dispatcher->setActionName('login');
        $dispatcher->setNamespaceName('Login\Controller');
        $dispatcher->setParam('goto', ltrim($_SERVER["REQUEST_URI"], '/'));
        $this->view->setViewsDir($this->registry->directories->modules . 'Login/View');
        return $dispatcher->forward(array());
    }
}

I came here looking for a simular issue where returning false did not work as 'temuri' suggested. This was caused when I had multiple 'listeners' on the 'dispatcher:beforeExecuteRoute' event.

The bug is known on: https://github.com/phalcon/cphalcon/issues/14675

To resolve this, also call $event->stop(); before returning false to resolve this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top