如何通过中间件Zend Framework 3将请求传递给Controller

时间:2017-10-20 09:59:18

标签: php model-view-controller middleware zend-framework3 zend-expressive

我正在使用ZendFramework 3组件开发REST API。 我决定使用中间件验证(验证)每个请求,如果请求有效,则传递给普通控制器操作以检索资源并发回响应。

  1. 这个概念是否正确?使用中间件来包装控制器?

  2. 如何通过以下代码和配置将请求传递给控制器​​?中间件

  3. //file: myapp/module/Auth/src/Middleware/Authorize.php
    
    namespace Auth\Middleware;
    
    use Interop\Http\ServerMiddleware\DelegateInterface;
    use Interop\Http\ServerMiddleware\MiddlewareInterface;
    use Psr\Http\Message\ServerRequestInterface;
    use Zend\Json\Json;
    use Zend\Http\Response;
    use Zend\Diactoros\Response\JsonResponse;
    use Zend\Diactoros\Response\RedirectResponse;
    
    class Authorize
    {
        public function __invoke($request, $response)
        {
            // Validate $request code goes here ...
    
            $response->getBody()->write('Hello World!');
            return $response;
        }
    }
    

    路由器配置

    //file: myapp/module/Auth/config/module.config.php
    namespace Auth;
    
    use Zend\Router\Http\Segment;
    use Zend\ServiceManager\Factory\InvokableFactory;
    use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
    
    return [
        'controllers' => [
            'factories' => [
                Controller\AuthController::class =>Controller\Factory\AuthControllerFactory::class,
            ],
    
        ],
    
        'service_manager' => [
            'factories' => [
                \Zend\Authentication\AuthenticationService::class => Service\Factory\AuthenticationServiceFactory::class,
                Service\AuthAdapter::class => Service\Factory\AuthAdapterFactory::class,
                Service\AuthManager::class => Service\Factory\AuthManagerFactory::class,
                Middleware\Authorize::class => InvokableFactory::class,
            ],
        ],
    
        'router' => [
            'routes' => [
                'auth' => [
                    'type'    => Segment::class,
                    'options' => [
                        'route' => '/auth[/:action[/:id]]',
                        'constraints' => [
                            'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                            'id'     => '[0-9]+',
                        ],
                        'defaults' => [
                            'controller' => Controller\AuthController::class,
                            'action'     => 'index',
                        ],
                    ],
                ],
                'user' => [
                    'type'    => Segment::class,
                    'options' => [
                        'route' => '/user[/:action[/:id]]',
                        'constraints' => [
                            'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                            'id'     => '[0-9]+',
                        ],
                        'defaults' => [
                            'middleware' => [
                                Middleware\Authorize::class,
                                Controller\UserController::class,
                            ],
                            'controller' => Controller\UserController::class,
                            'action'     => 'index',
                        ],
                    ],
                ],
            ],
        ],
    
        'view_manager' => [
            'template_path_stack' => [
                'auth' => __DIR__ . '/../view',
            ],
        ],
    
        'doctrine' => [
            'driver' => [
                __NAMESPACE__ . '_driver' => [
                    'class' => AnnotationDriver::class,
                    'cache' => 'array',
                    'paths' => [__DIR__ . '/../src/Entity']
                ],
                'orm_default' => [
                    'drivers' => [
                        __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
                    ]
                ]
            ]
        ],
    ];
    

1 个答案:

答案 0 :(得分:0)

所以,看看你的代码,让我感到震惊的是以下配置:

'defaults' => [
    'middleware' => [
        Middleware\Authorize::class,
        Controller\UserController::class,
    ],
    'controller' => Controller\UserController::class,
    'action'     => 'index',
],

您只能使用其中一个选项,而不能同时使用这两个选项,因为在ZF3​​中,中间件是从event listener调度的,因此会禁用传统调度循环的其余部分。

因此,您可以删除控制器和操作行。

对于其余部分,概念是正确的,您肯定可以通过这种方式添加身份验证。如果您刚刚开始使用您的项目,我建议您使用Zend Expressive。对您而言,不同之处在于您可以在任何其他中间件之前应用身份验证操作,而在ZF3中,您必须手动将其添加到每个路由。