Framework: Laravel 5.6 Lost Session after Middleware

Created on 29 Aug 2018  路  2Comments  路  Source: laravel/framework

  • Laravel Version: 5.6
  • PHP Version: 7.1
  • Database Driver & Version:

Description:

Hello I have the similar problem as #13000 but i don't understand how to solve it.

After login, i put an object in session.
Then in my custom middleware i want to use this object but it's empty.

Since Laravel 5.3, all route in web.php are in the middlewaregroup web.
So i don't understand why session is not working.

Steps To Reproduce:

My web.php :

Route::get('/shareaccess/{albumid}/{shareid}', 'ShareAccessController@show')->name('shareaccess');
Route::post('/shareaccess/{albumid}/{shareid}/validate', 'ShareAccessController@login')->name('loginshareaccess');

Auth::routes();

//Album Routes`
Route::get('/album/{albumid}', 'AlbumController@index')->middleware('is_admin')->name('album');

My kernel.php

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    // Dev tools for debugging
    \Clockwork\Support\Laravel\ClockworkMiddleware::class,
];

/**
 * The application's route middleware groups.
 *
 * @var array
 */
protected $middlewareGroups = [
    'web' => [
        //note that all route specified in web.php applies this middleware
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\Session\Middleware\AuthenticateSession::class, //https://kfirba.me/blog/the-undocumented-authenticatesession-middleware-decoded
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \App\Http\Middleware\IsShare::class,
    ],

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

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'is_admin' =>  \App\Http\Middleware\IsAdmin::class,
];

My MiddleWare IsShare.php

public function handle($request, Closure $next)
{

    log::debug('ShareMiddleware : user : ' . \Auth::user());

    if (\Auth::user()) {
        if(\Auth::user()->isShare()) {
            $share = Session::get('share');
                //do some stuff
                return $next($request);
        }
    }
return $next($request);
}

My Controller : shareaccess.php

     public function show($albumid, $shareid, Request $request)
     {
         log::debug('ShareAccessController show : albumid : ' . $albumid . ' shareid : ' . $shareid);

         return view('auth.shareaccess', ['albumid' => $albumid, 'shareid' => $shareid]);
     }

     public function login($albumid, $shareid, Request $request)
     {
         $this->validate($request, [
             'email' => ['required', 'email'],
          ]);

         $album = Album::find($albumid);
         log::debug('ShareAccessController login : albumid : ' . $albumid);
         $share = $album->shares()-> where('id', $shareid)->where('email', $request->email)->first();

         if ($share) {
             log::debug('ShareAccessController login : share found : ' . $share->email . ' ' . $share->active );
             $user = User::where('email', '[email protected]')->first();
             Auth::loginUsingId($user->id);
             log::debug('ShareAccessController : login : user authenticated : ' . Auth::user()->email);

             Session::put('share', $share);

             log::debug('ShareAccessController login : share in Session  : ' . Session::get('share'));
         }
         log::debug('validateshare : route : ' . route('album', ['albumid' => $albumid]));

         return redirect()->route('album', ['albumid' => $albumid]);

     }

Most helpful comment

If you want to manipulate the value you just in put in the session on your controller , @pierDipi answer is correct, you should use an after middleware, the docs have good coverage on this, but here is an example:

~~~php
// in your middleware
public function handle($request, Closure $next) {
// first you process the request ans save the response, so your controller is
// executed before the middleware and the session i populated
$response = $next($request);

// now you can access the values shared on this very request
if($request->user() && $request->user()->isShare()) {
  // do some stuff
}

return $response; // don't forget to return the response to the user

}
~~~

All 2 comments

As this comment suggests note that all route specified in web.php applies this middleware in App\Http\Kernel.php, first the handle method of isShare middleware is performed and after the login method of ShareAccessController, therefore the session with the key 'share' is an empty collection. If you want to run the middleware after the login method check the documentation https://laravel.com/docs/5.3/middleware#defining-middleware , section _Before & After Middleware_
I hope I have been helpful.

If you want to manipulate the value you just in put in the session on your controller , @pierDipi answer is correct, you should use an after middleware, the docs have good coverage on this, but here is an example:

~~~php
// in your middleware
public function handle($request, Closure $next) {
// first you process the request ans save the response, so your controller is
// executed before the middleware and the session i populated
$response = $next($request);

// now you can access the values shared on this very request
if($request->user() && $request->user()->isShare()) {
  // do some stuff
}

return $response; // don't forget to return the response to the user

}
~~~

Was this page helpful?
0 / 5 - 0 ratings