Reputation: 4498
I'm trying to build some authorization into my Phalcon-based app. In my bootstrap file I instantiate my Auth class (which extends Component), and run my authorize()
function. Inside that function I get the dispatcher by calling $Dispatcher = $this->di->getShared('dispatcher')
.
That all seems to run fine. However, when I then call $Dispatcher->getControllerName()
, it returns NULL.
How do I access the controller name?
Here is my bootstrap file:
$Debug = new \Phalcon\Debug();
$Debug->listen();
#try{
# Create a Dependency Injection container
$DI = new \Phalcon\DI\FactoryDefault();
# Load config
$Config = require '../app/config/config.php';
$DI->setShared('config',$Config);
# Register an autoloader
$Loader = new \Phalcon\Loader();
$Loader->registerDirs($Config->phalcon->load_dirs->toArray());
$Loader->registerNamespaces($Config->phalcon->namespaces->toArray());
$Loader->register();
# Initialize Session
$Session = new \Phalcon\Session\Adapter\Files();
$Session->start();
$DI->setShared('session',$Session);
# Set up the View component
$DI->set('view',function() use($Config){
$View = new \Phalcon\Mvc\View();
$View->setViewsDir($Config->dir->views_dir);
$View->registerEngines(['.phtml'=> function($View,$DI) use ($Config){
$Volt = new \Phalcon\Mvc\View\Engine\Volt($View,$DI);
$Volt->setOptions([ 'compiledPath' => $Config->dir->views_compile_dir,
'compileAlways' => $Config->app->views_compile_always
]);
return $Volt;
}
]);
$View->Config = $Config;
return $View;
});
# Check authorization
$Auth = new Auth($DI);
if($Auth->authorize()){
$DI->setShared('user',$Auth->getUser());
}
else{
$DI->get('view')->render('system','notallowed');
exit();
}
# Set up connection to database
$DI->set('db',function() use($Config){
return new \Phalcon\DB\Adapter\Pdo\Mysql([ 'host' => $Config->database->host,
'dbname' => $Config->database->database,
'username' => $Config->database->username,
'password' => $Config->database->password
]);
});
# Set up base URL
$DI->set('url',function() use($Config){
$URL = new \Phalcon\Mvc\Url();
$URL->setBaseUri('/'.basename($Config->dir->app_dir_web));
return $URL;
});
# Set up message flashing to use session instead of direct
$DI->set('flash',function(){
return new \Phalcon\Flash\Session();
});
# Handle the requested URL
$App = new \Phalcon\Mvc\Application($DI);
# Echo the output
echo $App->handle()->getContent();
/*
}
catch(\Phalcon\Exception $e){
echo 'Phalcon Exception: ',$e->getMessage();
}
*/
Upvotes: 2
Views: 15304
Reputation: 1060
This is an old thread but in case people still need it, I will show you two ways to properly handle authorization.
In both cases, you should check authorization in a "before middleware", not anywhere else.
Checking authorization directly in your front controller is a bit premature.
Here you perform authorization checks only if needed. It is a bit more code, but a bit more effective too because you don't have to even use the database if you don't need to.
$app = \Phalcon\Mvc\Micro;
$app->before(function() use ($app)
{
/**
* @var \Phalcon\Mvc\Controller $oHandler
*/
$oHandler = null;
$sAction = null;
$aHandlerArr = (array)$app->getActiveHandler();
if (!empty($aHandlerArr) && !empty($aHandlerArr[1]))
{
$oHandler = $aHandlerArr[0];
$sAction = $aHandlerArr[1];
}
if ($oHandler && $oHandler->isAuthRequired($sAction))
{
// Do auth, and send an error if failed
}
});
The other way is to simply try authorization in your before middleware without checking if you need it. It is the same code as above, but without the handler retrieval.
$app = \Phalcon\Mvc\Micro;
$app->before(function() use ($app)
{
// Do auth ...
// Set member in your app, if auth succeeded.
// Then in your controller actions, simply check for the member in your app
});
Upvotes: 1
Reputation: 3331
I am using a Router object so the following works for me before the ->handle
call
/** @var $router \Phalcon\Mvc\Router */
$router = require APPLICATION_PATH.'/routes/default.php';
$router->handle($url);
$router->setUriSource(\Phalcon\Mvc\Router::URI_SOURCE_SERVER_REQUEST_URI);
/** @var $matched \Phalcon\Mvc\Router\Route */
$matched = $router->getMatchedRoute();
$paths = $matched->getPaths();
echo 'controller : ',$paths['controller'],"<br />";
echo 'action : ',$paths['action'],"<br />";
Upvotes: 1
Reputation: 2465
I think that untill you call $app->handle()
the dispatcher won't be properly setup.
Maybe not a direct response, but I've manage to successfully implement authorization using Vokuro app as a example: https://github.com/phalcon/vokuro.
Your bootstrap looks ok should work.
I'm using this in bootstrap file :
/**
* Handle the request
*/
$application = new \Phalcon\Mvc\Application();
$application->setDI($di);
if (!empty($_SERVER['REQUEST_URI'])) {
$uriParts = explode('?', $_SERVER['REQUEST_URI']);
$uri = $uriParts[0];
} else {
$uri = '/';
}
echo $application->handle($uri)->getContent();
As you can see there is $uri parameter passed to $application->handle()
function.
Inside controllers: $this->dispatcher->getControllerName()
works fine.
Upvotes: 4