Zend Framework 2 - Глобальная проверка подлинности с помощью ZFCUser

Я установил ZFCUser успешно. Теперь мне интересно, есть ли способ глобальной проверки подлинности.

Как указано в вики, есть несколько способов проверить подлинность. Все они работают, но нужно ли в каждом действии помещать условие проверки-if-if? Все мои сайты должны быть доступны только при входе в систему, а если нет, вы должны быть перенаправлены на страницу входа.

Кто-нибудь знает, есть ли центральное место, где я могу поместить эту логику?

5 ответов

Решение

Если честно, я не думаю, что это хорошая идея - блокировать каждую страницу для неаутентифицированного пользователя. Как бы вы получили доступ к странице входа?

Тем не менее, вы должны знать страницу, к которой осуществляется доступ, чтобы сделать белый список страниц доступным для анонимных посетителей. Для начала я бы предложил включить страницу входа. Вы можете проверить страницы проще всего, используя их маршрут. Поэтому проверьте текущий согласованный маршрут по белому списку. Если заблокирован, действуйте. В противном случае ничего не делать.

Пример будет внутри Module.php из модуля, например, вашего приложения:

namespace Application;

use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\RouteMatch;

class Module
{
    protected $whitelist = array('zfcuser/login');

    public function onBootstrap($e)
    {
        $app = $e->getApplication();
        $em  = $app->getEventManager();
        $sm  = $app->getServiceManager();

        $list = $this->whitelist;
        $auth = $sm->get('zfcuser_auth_service');

        $em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($list, $auth) {
            $match = $e->getRouteMatch();

            // No route match, this is a 404
            if (!$match instanceof RouteMatch) {
                return;
            }

            // Route is whitelisted
            $name = $match->getMatchedRouteName();
            if (in_array($name, $list)) {
                return;
            }

            // User is authenticated
            if ($auth->hasIdentity()) {
                return;
            }

            // Redirect to the user login page, as an example
            $router   = $e->getRouter();
            $url      = $router->assemble(array(), array(
                'name' => 'zfcuser/login'
            ));

            $response = $e->getResponse();
            $response->getHeaders()->addHeaderLine('Location', $url);
            $response->setStatusCode(302);

            return $response;
        }, -100);
    }
}

Вы можете использовать модуль ZF2 BjyAuthorize, чтобы блокировать / разрешать доступ к страницам на основе пользовательских ролей, таких как guest, user и т. д. с помощью controller guard, route guard так далее

На ZF 2.4.2 я делаю это в Module.php

class module {

protected $whitelist = array(
    'Application\Controller\Login'
);

public function onBootstrap(MvcEvent $e)
{

    $eventManager        = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);

    // add event
    $eventManager->attach('dispatch', array($this, 'checkLogin')); 

}

public function checkLogin($e)
{

    $auth   = $e->getApplication()->getServiceManager()->get("Zend\Authentication\AuthenticationService");
    $target = $e->getTarget();
    $match  = $e->getRouteMatch();

    $controller = $match->getParam('controller');

    if( !in_array($controller, $this->whitelist)){
        if( !$auth->hasIdentity() ){
            return $target->redirect()->toUrl('/login');
        }
    }

}

//other methods....
}

Люди,

Совет, не забудьте добавить "использовать" для исправления оператора RouteMatch:

use Zend\Mvc\Router\Http\RouteMatch;

Здесь нужно это:

if (!$match instanceof RouteMatch)...

Если вы забудете, если выше, есть непостоянный

Другим вариантом может быть создание собственного суперкласса абстрактного контроллера и реализация метода onDispatch() следующим образом:

public function onDispatch(MvcEvent $e) 
{
    // check authentication here

    return parent::onDispatch($e);
}

Вы можете также реализовать белый список:).

Другие вопросы по тегам