slimphp / Slim-Csrf

Slim Framework CSRF protection middleware
MIT License
338 stars 58 forks source link

CsrfExtension name & value empty in Twig Extension #85

Closed madsem closed 5 years ago

madsem commented 6 years ago

No matter what I try the getTokenName() & getTokenValue() methods always return null.

I copied and pasted the CsrfExtension straight from the the docs. Registered in my ViewServiceProvider and passed CsrfExtension the container instance of Guard.

function register()
    {
        $this->getContainer()
             ->share('view', function () {

                 $view = new Twig(base_path('resources/views/'), [
                     'cache' => base_path('storage/cache/views'),
                     'debug' => config()->get('app.debug') // this also auto reloads views cache if set to true
                 ]);

                 // Instantiate and add Slim specific extension
                 $uri = $this->getContainer()->get('request')->getUri()->getBasePath();
                 $basePath = rtrim(str_ireplace('index.php', '', $uri), '/');
                 $view->addExtension(
                     new TwigExtension($this->getContainer()->get('router'), $basePath)
                 );

                 // add app specific Twig extensions
                 $view->addExtension(
                     new CsrfExtension($this->getContainer()->get('csrf'))
                 );

                 return new View(
                     $view,
                     $this->getContainer()->get('request'),
                     $this->getContainer()->get('response')
                 );
             });
    }

If I do this though inside the CsrfExtension, I get key and value:

function getGlobals()
    {
        // CSRF token name and value
        $keyPair = $this->csrf->generateToken();

        return [
            'csrf' => [
                'field' => '
                <input type="hidden" name="' . $this->csrf->getTokenNameKey() . '" value="' . $keyPair['csrf_name'] . '">
                <input type="hidden" name="' . $this->csrf->getTokenValueKey() . '" value="' . $keyPair['csrf_value'] . '">
            ',
            ]
        ];
    }

Outputs:

array:2 [▼
  "csrf_name" => "csrf5b37612c206c8"
  "csrf_value" => "57e1d057703cb37a97eea2c6d85f5f65"
]

Is there anything wrong with doing it this way?

I'm just really curious why the other methods aren't working... Tried sifting through the source but am really unsure why this isn't working

phpwalter commented 6 years ago

I have...

    public function __invoke($request, $response, $next)
    {
        $this->container->view->getEnvironment()->addGlobal('csrf', [
            'field' => '
                <input type="hidden" name="' . $this->container->csrf->getTokenNameKey() . '" value="' . $this->container->csrf->getTokenName() . '">
                <input type="hidden" name="' . $this->container->csrf->getTokenValueKey() . '" value="' . $this->container->csrf->getTokenValue() . '">
            ',
        ]);

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

and I get in my TWIG template...

<input type="hidden" name="csrf_name" value="">
<input type="hidden" name="csrf_value" value="">

But if I drop $this->container->csrf->getTokenValueKey() into my AuthController::getSignIn() it gives me a value!

very very odd

infodusha commented 6 years ago

Fixes easy with changing middleware order: Add your csrf middleware before adding csrf test. Looks like after checking name and value clears. Example (in middleware.php):

$app->add(new \Src\Middleware\CsrfRendererMiddleware($container));
$app->add($container->get('csrf'));