tuupola / slim-jwt-auth

PSR-7 and PSR-15 JWT Authentication Middleware
https://appelsiini.net/projects/slim-jwt-auth
MIT License
821 stars 140 forks source link

$request->getAttribute("token"); - not works in my handler #211

Closed nrob81 closed 2 years ago

nrob81 commented 2 years ago

Hello,

I configured the middleware, the authentication works perfectly but i cannot access the decoded data in the "token" attribute.

Can somebody please help me out?

index.php

$routes = simpleDispatcher(function (RouteCollector $r) {                                                                                                     
    $r->get('/', MainPage::class);                                                                                                                            
    $r->post('/token', Token::class);                                                                                                                         
    $r->get('/info', Info::class);                                                                                                                            
}); 
...
$middlewareQueue = [                                                                                                                             
    new FastRoute($routes),                                                                                                                      
    new JwtAuthentication($configJwt),                                                                                                           
    new RequestHandler($container),                                                                                                              
];                                                                                                                                               

$requestHandler = new Relay($middlewareQueue);                                                                                                   
$response = $requestHandler->handle($request);                                                                                                   

I am trying to read the decoded token data in Info.php

class Info                                                                                                                                                      
  {                                                                                                                                                               
      private RequestInterface $request;                                                                                                                          
      private ResponseInterface $response;                                                                                                                        

      public function __construct(RequestInterface $request, ResponseInterface $response)                                                                         
      {                                                                                                                                                           
          $this->request = $request;                                                                                                                              
          $this->response = $response;                                                                                                                            
      }                                                                                                                                                           

      public function __invoke(): ResponseInterface                                                                                                               
      {                                                                                                                                                           
          $response = $this->response->withHeader('Content-Type', 'application/json');                                                                            

          $ret = $this->request->getAttribute('token');                                                                                                           
          $response->getBody()->write(json_encode($ret));     
// ret = null                                                                                                    

          return $response;                                                                                                                                       
      }                                                                                                                                                           
  }     

 [attributes:Laminas\Diactoros\ServerRequest:private] => Array
 (
 )

what am i doing wrong here? thanks

tuupola commented 2 years ago

What is the actual problem? Have you tried var_dump($this->request->getAttribute('token'));?

As a sidenote Info does not look like a PSR-15 middleware.

nrob81 commented 2 years ago

My problem is the

var_dump($this->request->getAttribute('token'));

returns NULL

the Info class is a route. i use these for /, /token and /info

tuupola commented 2 years ago

How does $configJwt look like? Is the middleware queue FIFO or LIFO? You could try reordering the middlewares.

nrob81 commented 2 years ago

i uploaded my code: https://github.com/nrob81/myrest

the configJwt is a simple class to hold the jwt config. i think the middleware queue is FIFO but not sure. is is passed to Relay\Relay

nrob81 commented 2 years ago

i forgot to mention that tried to reorder the middlewares.

tuupola commented 2 years ago

You might be using something else than the "live" request. I never used Relay myself but unit tests include testing of the token as attribute in the request and quick test with Slim also shows the attribute is there as expected.

$app = new App();

$app->add(new Tuupola\Middleware\JwtAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommittogithub",
    "path" => ["/protected"]
]));

$app->get("/protected", function ($request, $response, $arguments) {
    var_dump($request->getAttribute("token"));
});

$app->run();

Yields:

$ set TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MjE1ODY1NDYsImV4cCI6MTYyMTU5Mzc0Nn0.LQVsncFPlRB5yHrcF_REFvq5EiJwYvHY093OKGoBHKQ"
$ curl --include --header "Authorization: Bearer $TOKEN" http://localhost:8080/protected
HTTP/1.1 200 OK
Host: localhost:8080
Date: Thu, 02 Sep 2021 16:35:09 GMT
Connection: close
X-Powered-By: PHP/7.4.23
Content-Type: text/html; charset=UTF-8

array(2) {
  ["iat"]=>
  int(1630598209)
  ["exp"]=>
  int(1630605409)
}
nrob81 commented 2 years ago

ok, thank you for your help!

deckyazmi commented 1 year ago

I'am facing the same issue, How to solve it?

middleware

$app->add(new \Tuupola\Middleware\JwtAuthentication([
        "path" => ["/test"],
        'secure' => false,
        "attribute" => "decodedData",
        "secret" => $_ENV['JWT'],
        "algorithm" => ["HS256"],
        "error" => function ($response, $arguments) {
            $data["status"] = "error";
            $data["message"] = $arguments["message"];
            // return $response->getBody()->write("error");
            return $response
                ->withHeader("Content-Type", "application/json")->getBody()
                ->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
        }

Routes

//this is working
$app->get('/test', function (Request $request, Response $response) {
        $response = $request->getAttribute("decodedData");
        return $response;
    });

//this return NULL
$app->group('/login', function (Group $group){
        ...
        $group->post('/test', testAct::class);
    });

testAct

class testAct implements RequestHandlerInterface
{
    ...
    public function __construct(PDO $conn,LoggerInterface $logg)
    {
        ...
    }

    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        $data = $request->getAttribute("decodedData");

return NULL

tuupola commented 1 year ago

In your config you bind the middleware only to url's beginning with /test.

$app->add(new \Tuupola\Middleware\JwtAuthentication([
    "path" => ["/test"],
    ...

For more info see: https://github.com/tuupola/slim-jwt-auth#path

deckyazmi commented 1 year ago

I didn't realize that, thank you