slimphp / Slim

Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs.
http://slimframework.com
MIT License
11.98k stars 1.95k forks source link

Action executing twice when middleware is added #3049

Closed discry closed 3 years ago

discry commented 3 years ago

I'm building a simple app based on the excellent Slim 4 Tutorial https://odan.github.io/2019/11/05/slim4-tutorial.html

The structure is still fairly similar to the tutorial.

Every time I call any of my endpoints using Postman it executes my Actions twice (ie: \App\Action\UserGetAction) for a Get. I can confirm this is happening in my logs.

if I comment out the AuthMiddleware file in config/middleware.php the duplicate action stops happening.

Any ideas?

I have created my own Auth middleware and added it in the config/middleware.php file:


use Selective\BasePath\BasePathMiddleware;
use Slim\App;
use Slim\Middleware\ErrorMiddleware;
use SlimSession\Helper;
use App\Factory\SessionFactory;
**use App\Factory\AuthMiddleware;**

return function (App $app) {
    // Parse json, form data and xml
    $app->addBodyParsingMiddleware();

    // Add the Slim built-in routing middleware
    $app->addRoutingMiddleware();

    $app->add(BasePathMiddleware::class); 

    // Catch exceptions and errors
    $app->add(ErrorMiddleware::class);

    **$app->add(AuthMiddleware::class); // <--- here**

    $loggerFactory = $app->getContainer()->get(\App\Factory\LoggerFactory::class);
    $logger = $loggerFactory->addFileHandler('error.log')->createInstance('error');

    $errorMiddleware = $app->addErrorMiddleware(true, true, true, $logger);

};

for simplicity I have stripped out pretty much everything in the AuthMiddleware:


namespace App\Factory;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
use GuzzleHttp\Client;
use Exception;
use App\Factory\LoggerFactory;

class AuthMiddleware
{

  /**
    * @var LoggerInterface
    */
   private $logger;

  public function __construct(LoggerFactory $logger)
  {
      $this->logger = $logger
            ->addFileHandler('user_edit.log')
            ->addConsoleHandler()
            ->createInstance('user_edit');
  }

    /**
     * Example middleware invokable class
     *
     * @param  ServerRequest  $request PSR-7 request
     * @param  RequestHandler $handler PSR-15 request handler
     *
     * @return Response
     */

    public function __invoke(Request $request, RequestHandler $handler): Response
    {

        $response = $handler->handle($request);
        $headers = $request->getHeaders();

        $eauth = $headers["Authorization"][0];

        $this->logger->info($eauth);

        return $handler->handle($request);

    }

} //Class

here are my routes in config/routes.php:

    $app->post('/users', \App\Action\UserCreateAction::class);
    $app->map(['PUT', 'PATCH'],'/users/{id}[/{system}]', \App\Action\UserUpdateAction::class);
    $app->delete('/users/{id}[/{system}]', \App\Action\UserDeleteAction::class);
    $app->get('/users/{id}[/{system}]', \App\Action\UserGetAction::class);
    $app->get('/extid/{id}[/{system}]', \App\Action\ExtidGetAction::class);

I have confirmed that I'm only running $app-run() once --- at the end of my index.php


require __DIR__ . '/../config/bootstrap.php';

$app->run();
discry commented 3 years ago

I have posted this as a question in stack overflow

l0gicgate commented 3 years ago

It looks as if you have added ErrorMiddleware twice in your example. I don't think that would cause it but just pointing that out.