jupitern / slim3-skeleton

Slim3 skeleton (http + cli) with some add-ons out of the box
44 stars 12 forks source link

Middleware question #7

Closed adrian0007 closed 6 years ago

adrian0007 commented 6 years ago

Hi, I implemented the JWT Authentication as a service provider (as per this example), but I'm still having trouble accessing the 'decoded' data this service seems to store in the 'attribute' of the request.

The decoded data ($request->getAttribute('token')) is accessible to routes.php, but once I'm inside a controller, this no longer works (as controllers use RequestInterface instead of ServerRequestInterface).

I have the same question regarding accessing a POST request submitted data ($request->getBody()) from inside a controller.

I have tried to set up containers and follow many different examples I could find online, but I don't think that I'm integrating them correctly according to the structure of this skeleton...

jupitern commented 6 years ago

Hi,

In \App\Http\Controller file the constructor gets injected with Request, Response, View and Logger using auto-wiring (code bellow). You can change this to whatever params you wan't. I'm not sure we should inject RequestInterface or ServerRequestInterface or both. What's the difference?!

In you controller you can then do $this->request->getQueryParam('searchTerm', '') for query params for example. In your case try adding ServerRequestInterface in Controller params and in your controller do $this->request->getAttribute('token');

tell me if it worked.

/**
   * @param \Psr\Http\Message\RequestInterface $request
   * @param \Psr\Http\Message\ResponseInterface $response
   * @param \League\Plates\Engine $view
   * @param \Psr\Log\LoggerInterface $logger
   */
public function __construct(Request $request, Response $response, Engine $view, LoggerInterface $logger)
{
    $this->request = $request;
    $this->response = $response;
    $this->view = $view;
    $this->logger = $logger;
}
jupitern commented 6 years ago

I think I should change to ServerRequestInterface https://github.com/slimphp/Slim/issues/1429

I have commited a fix to master master branch. can you try it?

adrian0007 commented 6 years ago

I agree with using ServerRequestInterface - I tried it myself before I posted here, but I didn't think to change the app.php, now it makes sense why it didn't work as well as yours... The latest commit fixes the request data $this->request->getBody();, very happy to see it work, thank you for the fix :)

The token returns a null object when called from within the controller, but returns the expected values in routes. This is not only true for the token, the entire $this->request->getAttributes() or $this->request->getQueryParam('token', '') also seem to be null inside the controller.

jupitern commented 6 years ago

I have never used jwt but can you share your provider and route code so I can find why it's not available in the controller?

adrian0007 commented 6 years ago

Sure, please find below the routes.php:

$app->any('/v1/{class}/{method}[/{id}]', function (Request $request, Response $response, $args) use($app) {
    return $app->resolveRoute('\App\Controller\Test', $args['class'], $args['method'], $args);
});

and the provider code:

<?php
declare(strict_types=1);
namespace App\ServiceProviders;
use Tuupola\Middleware\JwtAuthentication;

class JwtAuth implements ProviderInterface
{
    public static function register()
    {
        $container = app()->getContainer();

        app()->add(new JwtAuthentication([
            "secret" => "supersecretkeyyoushouldnotcommittogithub",
            "path" => "/",
            "ignore" => ["/v1/Auth"],
            "algorithm" => ["HS256"],
            "error" => function ($response, $arguments) {
                throw new \Exception('Authentication error :: ' . $arguments["message"]);
            },
            "before" => function ($request, $arguments) use ($container) {
//                return $request->getAttributes();
            }
        ]));
    }
}

According to the documentation, the attribute is stored by default in 'token', unless otherwise specified (for example "attribute" => "jwt" - also tried).

jupitern commented 6 years ago

Hi, I haven't had the time to follow up on this. Did you managed to put htis together?