jshannon63 / laravel-psr15-middleware

Use your PSR-15 compliant middleware in Laravel
MIT License
13 stars 5 forks source link

Sessions get lost #1

Closed ghost closed 6 years ago

ghost commented 6 years ago

When using the Psr15MiddlewareServiceProvider alongside Laravel's Illuminate\Foundation\Http\Middleware\VerifyCsrfToken, the token changes on every request and the verification fails on every form posted.

I'm using the VeryCsrfToken Middleware as following in Kernel.php:

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

As I found out, the SessionID changes at least after every post-request.

jshannon63 commented 6 years ago

~could you provide your /config/psr15middleware.php configuration file. I will try to track down what is happening.~ I believe I have identified and corrected issue. I will tag a new release with the update. It seems that the psr15 group middleware was being processed even if none were defined. Although it seems this should not be an issue, actually it was causing the request to get partially sterilized as it passed through. @dandjo please try v1.4 release on your setup/installation and provide feedback if you can. Thanks for the notification.

ghost commented 6 years ago

I've testet v1.4 with my setup. With no middlewares configured in /config/psr15middleware.php everything works. If i configure at least one middleware (does not matter which one), the session gets lost again. Here's my config:

<?php
return [
    'middleware' => [
        Middlewares\ClientIp::class,
        App\Http\Middleware\Psr15\Example::class,
    ],
    'groups' => [
        'web' => [
        ],
        'api' => [
        ],
        'custom' => [
        ],
    ],
    'aliases' => [
    ]
];
ghost commented 6 years ago
(1/1) TokenMismatchException
in VerifyCsrfToken.php (line 68)
--
at VerifyCsrfToken->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in AuthenticateSession.php (line 39)
at AuthenticateSession->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in ShareErrorsFromSession.php (line 49)
at ShareErrorsFromSession->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in StartSession.php (line 64)
at StartSession->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in AddQueuedCookiesToResponse.php (line 37)
at AddQueuedCookiesToResponse->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in EncryptCookies.php (line 59)
at EncryptCookies->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in Pipeline.php (line 102)
at Pipeline->then(object(Closure))in Router.php (line 574)
at Router->runRouteWithinStack(object(Route), object(Request))in Router.php (line 533)
at Router->dispatchToRoute(object(Request))in Router.php (line 511)
at Router->dispatch(object(Request))in Kernel.php (line 176)
at Kernel->Illuminate\Foundation\Http\{closure}(object(Request))in Pipeline.php (line 30)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in Debugbar.php (line 51)
at Debugbar->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in TransformsRequest.php (line 30)
at TransformsRequest->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in TransformsRequest.php (line 30)
at TransformsRequest->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in ValidatePostSize.php (line 27)
at ValidatePostSize->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in CheckForMaintenanceMode.php (line 46)
at CheckForMaintenanceMode->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in Psr15Middleware.php (line 28)
at Psr15Middleware->handle(object(Request), object(Closure))in Pipeline.php (line 148)
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))in Pipeline.php (line 53)
at Pipeline->Illuminate\Routing\{closure}(object(Request))in Pipeline.php (line 102)
at Pipeline->then(object(Closure))in Kernel.php (line 151)
at Kernel->sendRequestThroughRouter(object(Request))in Kernel.php (line 116)
at Kernel->handle(object(Request))in index.php (line 53)
ghost commented 6 years ago

When I debug the $request in the Psr15Middleware.php, it gives me:

  +cookies: ParameterBag {#41 ▼
    #parameters: array:2 [▼
      "XSRF-TOKEN" => "eyJpdiI6IlwvNWticVFrRWs5TkRVKzZOeHBUeGRRPT0iLCJ2YWx1ZSI6IncxVEx4eTFkVEFUbkVTd1k2RWNqTExjZFF0b2dEcVJBTmh4TWZvTkZZMXJpV1pkRCtoVkxmTEZidUxmNUVaSDVuS3FTUnQxUWw0czJZ ▶"
      "laravel_session" => "eyJpdiI6IkV2UDZLOVZpbHNVd0xWRjdLKzlENUE9PSIsInZhbHVlIjoiS2pcL2ZqTEdxWTVwV2F2RFphUTFuOXBObk1iQ1pTNTNnWXFuUWxrUUxsa1phd0N3bzJEY3NiaHdFWnp2SFpcLzNHRkRhVTNhT0Z5dGJU ▶"
    ]
  }

In my ExampleMiddleware.php after the Dispatcher processed the request, the ServerRequestInterface $request gives me:

  -cookieParams: array:2 [▼
    "XSRF-TOKEN" => null
    "laravel_session" => null
  ]

Maybe something with cookies?

ghost commented 6 years ago

I found a setting that is working. If I manually add the Middleware in my Kernel.php, all Psr15Middlewares are working and the session persists.

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \Jshannon63\Psr15Middleware\Psr15Middleware::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

I deactivated the pusher in the ServiceProvider.

        $config = $this->app['config'];

        if(count($config->get('psr15middleware.middleware'))){
            if($config->get('psr15middleware')) {
                $this->app->singleton('Psr15Middleware', function () use ($config) {
                    return new \Jshannon63\Psr15Middleware\Psr15Middleware($config, 'middleware');
                });
                //$this->app[\Illuminate\Contracts\Http\Kernel::class]->prependMiddleware('Psr15Middleware');
            }

            foreach ($config->get('psr15middleware.groups') as $key => $group) {
                if(!count($group)){
                    continue;
                }

Any idea why this is working?

jshannon63 commented 6 years ago

What you sent is good information. That is actually how it was done in an earlier version. The service provider logic was added to support groups and aliases. I really appreciate your help so far. I am working on it now. Hopefully there will be a fix to the package soon.

jshannon63 commented 6 years ago

It took a bit, but I finally tracked down the issue to a faulty header on the response after conversion from psr7 back to foundation/laravel format. The minor differences between the symfony respone and the laravel response caused the problem. Added a new conversion method to update the laravel specific response object with new data from the foundation response.

Please check it if you have time (v1.5) and let me know. I appreciate the look into the issue.

ghost commented 6 years ago

Thank's for the fix. It works.