tuupola/slim-jwt-auth

JWT middleware is executing in wrong order of middlewares

agostinhodev opened this issue · 2 comments

I have a API that allow many companies to connect to them and use my services.
I have two files:

index.php

<?php

    require_once "config/env.php";
	require_once "../vendor/autoload.php";   
	    
    $app = new Slim\App(

        [

            'settings' =>[

                'displayErrorDetails' => true,

            ],

        ]

	);
	
    use src\middlewares\Empresa;
 
	$app->group('/v1', function () use ($app){
		
        require_once "./routes/usuario.php";
        require_once "./routes/pessoa.php";

    });

    $app->add( new Empresa );   // First middleware. Need to be executed in first time to check company HEADER and set enviroment variable
        
    $app->run();

?>

and one file called routes/pessoa.php


<?php

    use src\controllers\Pessoa;         
    use src\middlewares\JwtAuth;
    
    $app->group('/pessoa', function () use ($app){

        $app->post('', Pessoa::class . ":nova")->add(JwtAuth::validateToken()); // Second middleware. Need to be executed after first middleware and need to get access to the enviroment variable

    });

Note that i put a middleware called Empresa wich need to be executed before that JwtAuth middleware because it receive a HEADER from my request wich i send my client company's name to get a enviroment variable base on this HEADER name.

However, the JwtAuth is returning before that my Empresa middleware can be executed.

This is executing in wrong sequence in my perception.

What would be the problem?

src/middlewares.php

<?php 


    namespace src\middlewares;
    
    use src\database\Database;

    final class Empresa {

        private $empresas = [

            "businness1",
            "businness2"

        ];

        public function __invoke($request, $response, $next)
        {
            
            $empresa = isset($request->getHeaders()['HTTP_EMPRESA'][0]) ? $request->getHeaders()['HTTP_EMPRESA'][0] : NULL ;

            if(is_null($empresa)){  

                $response = $response->withJson([

                    "message" => "Informe a empresa corretamente"

                ])->withStatus(400);

            } else {

                if(!in_array($empresa, $this->empresas)){

                    $response = $response->withJson([

                        "message" => "A empresa informada não existe"

                    ])->withStatus(404);

                } else {

                    $request = $request->withAttribute('empresa', $empresa);

                    putenv("APP_NOME_EMPRESA=$empresa");

                    $response = $next($request, $response);

                }

            }
                 
            return $response;

        }
        
    }

src/middlewares/JwtAuth

<?php

    namespace src\middlewares;

    use Tuupola\Middleware\JwtAuthentication;
   
    final class JwtAuth{
             
        public function validateToken() : JwtAuthentication
        {


            $jwtkey = getenv('APP_NOME_EMPRESA');
            //Here's the wrong. According with the Slim doc, the first middleware added it's the last to be executed.
           // But in here i can't access the enviroment variable...
          // I need to know how company is requesting to generate a JWT verification. But this don't happen.

                       
            switch($type){

                default:
                case 'login':
                    
                    $jwtkey .= getenv('API_JWT_TOKEN_SUFIX');

                break;
               
            }
                
           return new JwtAuthentication([
    
                'secure' => false,
                'secret' => $jwtkey,
                'attribute' => 'jwt',
                'error' => function ($response, $arguments) {
                    
                    $data["message"] = $arguments["message"];
                    
                    return $response
                        ->withHeader("Content-Type", "application/json")
                        ->getBody()->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
                }

            ]);
            
            
            
        }   
      
    }

Middleware cannot affect the order it is executed. Both Slim 3 and 4 use LIFO. Meaning if you add middlewares as the following:

$app->add('middleware3');
$app->add('middleware2');
$app->add('middleware1');

The execution order will be:

  1. middleware1
  2. middleware2
  3. middleware3

Ie. If you want Empresa middleware to be executed first you need to add it last.

$app->add($jwtAuthentication);
$app->add($empresa);

If you are looking to use multiple keys, you can also pass them as anything which implements ArrayAccess.

 new JwtAuthentication([
     "secret" => [
         "xxxx" =>"supersecretkeyyoushouldnotcommittogithub",
         "yyyy" =>"anothersecretkeyfornevertocommittogithub"
     ]
]);

No feedback.