2016-09-27 2 views
1

Я работаю над альбомом Применение в zf3.I добавлена ​​функциональность аКЛ приложению, как это:Как реализовать ACL и авторизации в module.php в zf3

AlbumController.php

class AlbumController extends AbstractActionController 
{ 
protected $role; 
public function onDispatch(\Zend\Mvc\MvcEvent $e) 
{ 
    $userSession = new Container('user'); 
    if (!isset($userSession->email)) { 
     return $this->redirect()->toRoute('login'); 
    } 
    else { 
     $this->role = $userSession->role; 
     parent::onDispatch($e); 
     } 
    } 
public function checkPermission($role,$action) 
{ 
    if($role == 'admin'){ 
    $acl = new Acl(); 
    if ($acl->isAllowed('admin', 'AlbumController', $action)) { 
     return true; 
    } 
    } 
    return false; 
} 
public function editAction() 
{ 
    $action = 'edit'; 
    $permission = $this->checkPermission($this->role,$action); 
    if (!$permission) { 
     $this->flashMessenger()->addMessage('<div class="alert alert- danger" role="alert"><b>You dont have the privilege to edit!!</b></div>'); 
     return $this->redirect()->toRoute('album'); 
    } 
    $id = (int) $this->params()->fromRoute('id', 0); 

    if (0 === $id) { 
     return $this->redirect()->toRoute('album', ['action' => 'add']); 
    } 
    try { 
     $album = $this->table->getAlbum($id); 
    } catch (\Exception $e) { 
     return $this->redirect()->toRoute('album', ['action' => 'index']); 
    } 

    $form = new AlbumForm(); 
    $form->bind($album); 
    $form->get('submit')->setAttribute('value', 'Edit'); 

    $request = $this->getRequest(); 
    $viewData = ['id' => $id, 'form' => $form]; 
    if (! $request->isPost()) { 
     return $viewData; 
    } 

    $form->setInputFilter($album->getInputFilter()); 
    $form->setData($request->getPost()); 
    $edit = $request->getPost('submit', 'Cancel'); 
    if($edit == 'Cancel'){ 
     $this->flashMessenger()->addMessage('<div class="alert alert-danger" role="alert"><b>Cancelled by User...!!</b></div>'); 
     return $this->redirect()->toRoute('album'); 
    } 
    if (! $form->isValid()) { 
     $this->flashMessenger()->addMessage('<div class="alert alert-danger" role="alert"><b>Failed to Update...!!</b></div>'); 
     return $viewData; 
    }else{ 
     $this->table->saveAlbum($album); 
     $this->flashMessenger()->addMessage('<div class="alert alert-success" role="alert"><b>Record Updated Successfully...!!</b></div>'); 
    } 
    // Redirect to album list 
    return $this->redirect()->toRoute('album', ['action' => 'index']); 
} 
} 

Это работает отлично, теперь я хочу переместить функцию onDispatch в Module.php, но не знаю, как ее реализовать. Может кто-то мне поможет

Module.php

<?php 
namespace Album; 

use Album\Controller\AlbumController; 
use Album\Model\Album; 
use Album\Model\AlbumTable; 
use Zend\Db\Adapter\AdapterInterface; 
use Zend\Db\ResultSet\ResultSet; 
use Zend\Db\TableGateway\TableGateway; 
use Zend\ModuleManager\Feature\ConfigProviderInterface; 
use Zend\ModuleManager\Feature\AutoloaderProviderInterface; 
use Album\Model\LoginTable; 

class Module implements ConfigProviderInterface 
{ 
    public function getConfig() 
    { 
    return include __DIR__ . '/../config/module.config.php'; 
    } 

    public function getServiceConfig() 
    { 
    return [ 
     'factories' => [ 
      AlbumTable::class => function($container) { 

       $tableGateway = $container->get(Model\AlbumTableGateway::class); 
       return new AlbumTable($tableGateway); 
      }, 
      Model\AlbumTableGateway::class => function ($container) { 

       $dbAdapter = $container->get(AdapterInterface::class); 

       $resultSetPrototype = new ResultSet(); 
       $resultSetPrototype->setArrayObjectPrototype(new Album()); 
       return new TableGateway('album', $dbAdapter, null, $resultSetPrototype); 
      }, 
      Model\LoginTable::class => function($container) { 
      $tableGateway = $container->get(Model\LoginTableGateway::class); 
      $table = new LoginTable($tableGateway); 
      return $table; 
      }, 
        Model\LoginTableGateway::class => function ($container){ 
        $dbAdapter = $container->get(AdapterInterface::class); 
        $resultSetPrototype = new ResultSet(); 
        return new TableGateway('login', $dbAdapter, null, $resultSetPrototype); 
        } 
      ], 
      ]; 
} 

public function getControllerConfig() 
{ 
    return [ 
     'factories' => [ 
      Controller\AlbumController::class => function($container) { 
       return new Controller\AlbumController($container->get(Model\AlbumTable::class)); 
      }, 
      Controller\LoginController::class => function($container) { 
       return new Controller\LoginController($container->get(Model\LoginTable::class)); 
      }, 
      Controller\LogoutController::class => function($container){ 
       return new Controller\LogoutController($container->get(Model\LoginTable::class)); 
      }, 
     ], 
    ]; 
} 
} 
+0

Легче использовать это (отказ от ответственности, я автор) https://github.com/ Saeven/zf3-circlical-пользователь – Saeven

ответ

0

Вот как я его реализовал. В вашем Module.php, добавьте слушателя EVENT_DISPATCH, с закрытием в качестве обратного вызова, который будет вызывать ваш класс промежуточного разрешения:

class Module implements ConfigProviderInterface 
{ 
    public function getConfig() 
    { 
     return include __DIR__ . '/../config/module.config.php'; 
    } 

    public function onBootstrap(MvcEvent $e) 
    { 
     $app = $e->getApplication(); 
     $eventManager = $app->getEventManager(); 
     $serviceManager = $app->getServiceManager(); 

     // Register closure on event DISPATCH, call your checkProtectedRoutes() method 
     $eventManager->attach(MvcEvent::EVENT_DISPATCH, function (MvcEvent $e) use ($serviceManager) { 
      $match = $e->getRouteMatch(); 
      $auth = $serviceManager->get(Middleware\AuthorizationMiddleware::class); 
      $res = $auth->checkProtectedRoutes($match); 
      if ($res instanceof Response) { 
       return $res; 
      } 
     }, 1); 

     // Init ACL : could be improved 
     $this->initAcl($e); 
    } 

Вы должны иметь AuthorizationMiddlewareFactory (назовем его, как вы хотите):

<?php 

namespace MyModule\Factory; 

use Interop\Container\ContainerInterface; 
use MyModule\Middleware\AuthorizationMiddleware; 
use Zend\Authentication\AuthenticationService; 
use Zend\ServiceManager\Factory\FactoryInterface; 

class AuthorizationMiddlewareFactory implements FactoryInterface 
{ 
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 
    { 
     $authService = $container->get(AuthenticationService::class); 
     $acl = $container->get('Acl'); // II init it in bootstrap(), could be improved 
     $response = $container->get('Response'); 
     $baseUrl = $container->get('Request')->getBaseUrl(); 
     $authorization = new AuthorizationMiddleware($authService, $acl, $response, $baseUrl); 
     return $authorization ; 
    } 
} 

И ваш AuthorizationMiddleware класс:

<?php 

namespace MyModule\Middleware; 

use Symfony\Component\VarDumper\VarDumper; 
use Zend\Authentication\AuthenticationService; 
use Zend\Http\PhpEnvironment\Response; 
use Zend\Permissions\Acl\Acl; 
use Zend\Router\RouteMatch; 

class AuthorizationMiddleware 
{ 
    private $authService ; 
    private $acl; 
    private $response; 
    private $baseUrl; 

    /** 
    * AuthorizationMiddleware constructor. 
    * @param AuthenticationService $authService 
    * @param Acl $acl 
    * @param Response $response 
    * @param $baseUrl 
    */ 
    public function __construct(AuthenticationService $authService, Acl $acl, Response $response, $baseUrl) 
    { 
     $this->authService = $authService; 
     $this->acl = $acl; 
     $this->response = $response; 
     $this->baseUrl = $baseUrl; 
    } 

    public function checkProtectedRoutes(RouteMatch $match) 
    { 
     if (! $match) { 
      // Nothing without a route 
      return null ; 
     } 
     // Do your checks... 
} 

Он может быть улучшен, но у вас есть идея ... Смотрите также этот вопрос и ответы: ZF3 redirection after ACL authorization failed

Смежные вопросы