Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

anon9348's avatar

Laavel 5.3 session in controller

As you all know, in L5.3 there is no possibility to access the session in the controller constructor. My question is how the 'auth' middleware will work if it cannot access the session? How can it figure if the user is authenticated or not if it cannot access the session?

0 likes
12 replies
anon9348's avatar

I read the article but it does not answer nu question. Ar least this is my opinion.

nate.a.johnson's avatar

The article gives a solution... here's the quote and the code.

As an alternative, you may define a Closure based middleware directly in your controller’s constructor. Before using this feature, make sure that your application is running Laravel 5.3.4 or above:

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;

class ProjectController extends Controller
{
    public function __construct()
    {
        $this->middleware(function ($request, $next) {
            $this->projects = Auth::user()->projects;

            return $next($request);
        });
    }
}
TheNodi's avatar

@IulianClita

I think it depends on when the different components get resolved by the service container. The authenticate middleware calls the AuthManager which resolves the different Guards, in particular SessionGuard which type-hint SessionInterface in its constructor. Since the auth middleware is called after the Session middleware, when the guard is resolved the session has been already set.

On the other hand, the controller constructor can set middlewares which makes me think it's resolved before the middleware are run. In this case the controller cannot type-hint session/user because there've not been initialized yet (by session middleware and auth middleware).

pmall's avatar

I cant figure out why one could need to use auth in constructor. Why not just use it in actions?

Using auth()->user()->projects instead of $this->projects is not a big deal.

1 like
anon9348's avatar

@TheNodi this really seems like very reasonable explanation but the official documentation says something slightly different. It says you can use the auth middleware like $this->middleware ('auth'); in your controller constructor but it also says that in the controller constructor you do not have access to te session. These 2 aspects contradict in my opinion because the auth middleware needs access to the session to figure out of the user is authenticated.

TheNodi's avatar

@IulianClita

I think there's a temporal difference, in chronological order:

- Resolve Controller (No Session)
- Resolve Middleware 
-- Run SessionMiddleware (Set Session)
-- Run AuthMiddleware
--- Resolve SessionGuard (Session)
--- Perform auth
(A bunch of other stuffs)
- Run controller method
anon9348's avatar

But how can you resolve the controller without first resolving the middleware if it is called in the constructor?

anon9348's avatar

Also there is the web middleware group StartSession middleware that runs on every request before the controller is hit so it seems we have access to the session. I must study harder the inner workings of laravel because something does not feel right. I am pretty sure that my understanding is wrong. :)

TheNodi's avatar
TheNodi
Best Answer
Level 11

@IulianClita

It's the StartSession middleware that populates the session object and the Authenticate middleware that populate the user object.

I know the middlewares get executed before the controller's execution, but that doesn't mean the controller is resolved (instantiated) after the middleware execution.

At a very high level, the controller and the middlewares got instantiated first (aka constructor is called) then the middleware got executed (handle() gets called), then the controller's action gets executed (aka $controller->whatever() gets called). SessionGuard is the part of the authentication that needs session's information in the constructor, but it got instantiated in the handle() method of Authenticate, which runs after the handle method of StartSession (which populates the session).

With an example:

// Consider these as global variables
$session = null;
$user = null;
$middlewares = [];

// Step 1: Create the controller
// If we ask for the session here, we get null. The controller constructor can add elements to $mdidlewares.
$controller = new ExampleController(/** dependences **/);

// Step 2: Create the middlewares
$middlewares[] = new StartSession(/** dependences **/);
$middlewares[] = new Authenticate(/** dependences **/);

// Step 3: Run Middlewares
foreach ($middlewares as $middleware) {
    $middleware->handle();
    /*
    The session middleware populates the $session variable here.
    Then the Authenticate middleware asks for $session (already populated because StartSession is before it), and retrieves the user populating $user.
    */
}

// Step 4: Run Controller
// Here session and user have been set, so we can ask for them.
$controller->whatever();

This is ages away from Laravel code, but it might help you understand the succession of events.

2 likes

Please or to participate in this conversation.