Reputation: 2813
I have a route as follows:
$app->get('/manager/:page', $authenticate($app), function ($page) use ($app, $secretshibe) {
$app->render('manager/pages/' . $page . '.php', ['user' => $secretshibe->get_page($page, $app->view()->getData('user'))]);
});
to render users. I use $authenticate
to check user login, which is as follows:
$authenticate = function ($app) use ($secretshibe) {
return function () use ($app, $secretshibe) {
if (!isset($_SESSION['user'])) {
$_SESSION['urlRedirect'] = $app->request()->getPathInfo();
$app->flash('error', 'Please login to see that page');
$app->redirect('/login');
}
};
};
What I need to do, it have another logic check which checks if the user has paid. That can be obtained from $secretshibe->check_payment($username)
which returns a bool, so my final function looks like this.
$authenticate = function ($app) use ($secretshibe) {
return function () use ($app, $secretshibe) {
if (!isset($_SESSION['user'])) {
$_SESSION['urlRedirect'] = $app->request()->getPathInfo();
$app->flash('error', 'Please login to see that page');
$app->redirect('/login');
}
if (!$secretshibe->check_payment($_SESSION['user'])) {
$app->flash('error', 'Your account has been marked as unpaid. Please pay to continue usage.');
$app->redirect('/manager/payment');
}
};
};
The problem is that when it redirects to /manager/payment
it uses the same route function, which checks authentication the same way. This results in the page getting stuck in a redirect loop. In order to stop this, I need to check if the requested route is /manager/payment
before redirecting.
Because the $authenticate
function is called as middleware, it is invoked before the route function, meaning that I cannot simply pass $page
to it. What is the best way to prevent this redirect loop?
Upvotes: 0
Views: 1354
Reputation: 2869
You want to register $authenticate
as a Hook rather than as route Middleware.
$app->hook('slim.before.dispatch', $authenticate($app));
Alternately, you could use custom Middleware to register the hook. I've done that in quite a few projects. It might look something like this:
class MyMiddleware extends \Slim\Middleware
{
public function call()
{
$app = $this->app;
$authenticate = function ($app) use ($secretshibe) {
// ... snip ...
}
$app->hook('slim.before.dispatch', $authenticate($app));
$this->next->call();
}
}
Here's a recent example of using Middleware to register a hook from one of my personal projects.
Upvotes: 2
Reputation: 2113
are you sure you need a closure in your middleware ? you could get app form \Slim\Slim::getInstance()
.
Also route middleware passed one argument, the matching route.
$authenticate = function ($route) use ($secretshibe) {
// get the app instance
$app = \Slim\Slim::getInstance();
if (!isset($_SESSION['user'])) {
$_SESSION['urlRedirect'] = $app->request()->getPathInfo();
$app->flash('error', 'Please login to see that page');
$app->redirect('/login');
}
if ($route->getName() !== '/manager/payment' && !$secretshibe->check_payment($_SESSION['user'])) {
$app->flash('error', 'Your account has been marked as unpaid. Please pay to continue usage.');
$app->redirect('/manager/payment');
}
};
$app->get('/manager/:page', $authenticate, function ($page) use ($app, $secretshibe) {
$app->render('manager/pages/' . $page . '.php', ['user' => $secretshibe->get_page($page, $app->view()->getData('user'))]);
});
Upvotes: 0