Проверить маршрут через Slim Middlewhere

У меня есть следующий маршрут:

$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'))]);
});

для отображения пользователей. Я использую $authenticate для проверки входа пользователя, который выглядит следующим образом:

$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');
    }
  };
};

Что мне нужно сделать, это еще одна логическая проверка, которая проверяет, заплатил ли пользователь. Это можно получить из $secretshibe->check_payment($username), которая возвращает логическое значение, поэтому моя окончательная функция выглядит так.

$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');
    }
  };
};

Проблема в том, что когда он перенаправляет на /manager/payment, он использует ту же функцию маршрута, которая точно так же проверяет аутентификацию. Это приводит к тому, что страница застревает в цикле перенаправления. Чтобы остановить это, мне нужно проверить, является ли запрошенный маршрут /manager/payment перед перенаправлением.

Поскольку функция $authenticate вызывается как промежуточное ПО, она вызывается перед функцией маршрута, а это означает, что я не могу просто передать ей $page. Каков наилучший способ предотвратить этот цикл перенаправления?


person Benedict Lewis    schedule 07.04.2014    source источник


Ответы (2)


Вы хотите зарегистрировать $authenticate как хук, а не как ПО промежуточного слоя маршрута.

$app->hook('slim.before.dispatch', $authenticate($app));

В качестве альтернативы вы можете использовать специальное ПО промежуточного слоя для регистрации ловушки. Я делал это в нескольких проектах. Это может выглядеть примерно так:

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();
    }
}

Вот недавний пример использования Middleware для регистрации хука из одного из моих личных проектов.

person Jeremy Kendall    schedule 08.04.2014

Вы уверены, что вам нужно закрытие в промежуточном программном обеспечении? вы можете получить форму приложения \Slim\Slim::getInstance().

Также промежуточное ПО маршрута передало один аргумент, соответствующий маршрут.

$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'))]);
});
person MamaWalter    schedule 07.04.2014