Zend框架2 -使用ZFCUser进行认证的全局检查


Zend Framework 2 - Global check for authentication with ZFCUser

ZFCUser安装成功。现在我想知道是否有一种方法可以全局检查身份验证。

正如wiki中概述的那样,有几种检查授权的方法。他们都工作,但我必须把检查-如果-子句真的在每一个动作?我所有的网站应该只有在登录时才能访问,如果没有,你应该被重新路由到登录页面。

有没有人知道我是否可以把这个逻辑放在一个中心位置?

老实说,我不认为为未经身份验证的用户阻止每个页面是一个好主意。您如何访问登录页面?

也就是说,您必须知道正在访问的页面,以便为匿名访问者创建可访问的页面白名单。首先,我建议包含登录页面。您可以通过使用它们的路由来最容易地检查页面。因此,请根据白名单检查当前匹配的路由。如果受阻,采取行动。否则,不执行任何操作。

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

在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....
}

您可以使用ZF2模块BjyAuthorize来阻止/允许访问基于用户角色的页面,如guest, user等使用controller guard, route guard

人物,

提示,不要忘记添加"use"来纠正RouteMatch语句:

use Zend'Mvc'Router'Http'RouteMatch;

这里需要这个:

if (!$match instanceof RouteMatch)...

如果你忘记了,上面的If有不固定的

另一种选择可能是创建自己的抽象控制器超类并实现onDispatch()方法,如下所示:

public function onDispatch(MvcEvent $e) 
{
    // check authentication here
    return parent::onDispatch($e);
}

您也可以在那里实现白名单:)。