Как передать запрос в контроллер через промежуточное ПО Zend Framework 3
Я разрабатываю REST API с компонентами ZendFramework 3. Я решил проверить (Аутентифицировать) каждый запрос, используя промежуточное программное обеспечение, и, если запрос действителен, тогда перейти к обычному действию контроллера для извлечения ресурсов и отправки ответа обратно.
Правильно ли это понятие? используя промежуточное ПО для обертывания контроллера?
Как передать запрос контроллеру с указанным ниже кодом и конфигурацией? Middleware of
//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 ответ
Итак, глядя на ваш код, меня поразил следующий конфиг:
'defaults' => [
'middleware' => [
Middleware\Authorize::class,
Controller\UserController::class,
],
'controller' => Controller\UserController::class,
'action' => 'index',
],
Вы можете использовать только один из этих вариантов, но не оба, и это потому, что промежуточное ПО ZF3 отправляется из прослушивателя событий, поэтому отключается оставшаяся часть традиционного цикла диспетчеризации.
Поэтому вы можете удалить как контроллер, так и линии действий.
В остальном, концепция верна, и вы определенно можете добавить Аутентификацию таким образом. Если вы только начинаете свой проект, я бы порекомендовал вам использовать Zend Expressive. Для вас разница будет в том, что вы можете применить свое действие аутентификации перед любым другим промежуточным программным обеспечением, в то время как в ZF3 вам придется добавлять его к каждому маршруту вручную.