We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Route authentication

Hello, I'm writing an application and I want to secure some routes, but not all. I've built an Auth Controller to handle the routes that must be secure. However, when I test a simple implementation, the route is still executed. I have pasted my code below. The $user is NULL and the if(empty($user)) {...} is executed, but the page does not redirect to "/"... I get "list" written on the page no matter what. You can see the result here: https://107.170.228.134/promotions/list

<?php

use Phalcon\Http\Response;

class AuthController extends ControllerBase {

    public function beforeExecuteRoute() {
        $user = $this->session->get('auth');
        if (empty($user)) {
            $response = new Response();
            return $response->redirect("/",false);
        }
    }

    public function listAction() {
        echo "list";
    }
}


58.4k
Accepted
answer
edited Jun '15

Hi

I think you should add beforeExecuteRoute() to controllerBase, In as example below

     // class ControllerBase
     class ControllerBase extends Controller{
     use Phalcon\Mvc\Dispatcher;
      [...]
      /**
     * @var array
     */
    private $unsecuredRoutes = [
        ['controller' => 'auth', 'action' => 'login'],
        ['controller' => 'auth', 'action' => 'signup'],
        ['controller' => 'auth', 'action' => 'register'],
        ['controller' => 'auth', 'action' => 'logout'],
        ['controller' => 'auth', 'action' => 'forgotpassword'],
        ['controller' => 'auth', 'action' => 'resetpassword']
    ];

    /**
     * @param Dispatcher $dispatcher
     *
     * @return bool
     */
    public function beforeExecuteRoute(Dispatcher $dispatcher)
    {
        if (!$this->session->has('auth') && !$this->isUnsecuredRoute($dispatcher)) {
            $dispatcher->forward(['controller' => 'auth', 'action' => 'login']);

            return false;
        }
    }

        /**
     * @param Dispatcher $dispatcher
     *
     * @return bool
     */
    private function isUnsecuredRoute(Dispatcher $dispatcher)
    {
        foreach ($this->unsecuredRoutes as $route) {
            if ($route['controller'] == $dispatcher->getControllerName()
                && $route['action'] == $dispatcher->getActionName()
            ) {
                return true;
            }
        }

        return false;
    }


17.5k

Thanks, I'll try that & see how it works.



17.5k
edited Jun '15

Actually, ended up being easier because I handle all of my secure routes in two controllers... Added this to ControllerBase and it's all good! Thanks for your help though... It was your answer that led me to this solution.

    public function beforeExecuteRoute(Dispatcher $dispatcher) {
        $user = $this->session->get('auth');
        $controller = $dispatcher->getControllerName();
        if (empty($user) && ($controller == "auth" || $controller == "authajax")) {
            $dispatcher->forward(['controller'=>'noauth','action'=>'login']);
        }
    }