mauro.b45@Gmail.com's avatar

Laravel5.3 - controller auth problems

Hi,

I have an error after upgrading my project to 5.3. I am sharing the user across all my controllers and views, however now Im getting null. This is my code

/**
     * BaseController constructor.
     */
    public function __construct()
    {
        $this->user = \Auth::user();

        view()->share('user', $this->user);
    }

I think at this point the AuthManager has not been executed (Actually, it is being executed event before the middleware) . I have dumped my code in the controller (null value) and in the middleware (Auth::User() does actually have the user object).

Was it any change in the bootstrap order or am I missing any other change for the upgrade?

Thanks,

0 likes
26 replies
Jaytee's avatar
  1. I wouldn't of updated to 5.3 just yet, it's still a couple of weeks until release.
  2. Authentication Controllers have changed in 5.3, if you create a fresh test project, you'll see there is now an AuthenticationController, PasswordController and others.
mauro.b45@Gmail.com's avatar

Hi @Jaytee. Thanks for the response

  1. It is a personal project, so I am just playing around with the new stuff. However I think I will need to rollback the changes.
  2. I did the change of the authentication. The real issue is that at the moment when the controller '__construct' is called the auth()_>user() is null. After that, the 'auth' middleware is called and it actually has a value.

The interesting part is the controller construct is being called before the middleware. This used to be the other way around.

I wonder if anyone has the same problem.

1 like
mauro.b45@Gmail.com's avatar

I debugged my code and apparently I cannot use Auth in the controller constructor anymore.

When the controller is created the StartSession middleware has not been run yet. This middleware uses the Illuminate\Session\Store driver to load the session. Hope this issue is fixed before the release or I will need to send the user to the view on every method.

1 like
fugues's avatar

I got the same problem, i used to store the auth user on the base controller, but as @mauro.b45@Gmail.com said, the value is null and i don't want to declare the auth user on each controller.

sietzekeuning's avatar

Running into the same problem.. Hope this will be sorted in the final release.

Oyed's avatar

Has anyone found a way around this yet?

sietzekeuning's avatar

That's not the point though. The point is you should be able to access the authenticated user in the constructor of your (base) controller.

5 likes
fugues's avatar

@sietzekeuning i agree with you, or should i declare on each one of my methods or call the auth user? whats no the best way i think!

raffjones's avatar

+1 for this issue.

I'm right with @sietzekeuning in thinking that being able to access to an authorised user in the constructor of a base controller is pretty important. I can't figure out why it's accessible in the subclassed controllers but not the base controller.

I'm using a repository pattern, and the UserRepositoryContract is passed into my BaseController as a dependency. I have a function in the repo to return the current logged-in user, but that is now returning null, so all Controllers are failing. I don't access Auth::user() directly anywhere.

If this is not being seen as an issue by the Laravel team (any steer, @TaylorOtwell or @JeffreyWay ?) then it would be good to know when, and how, we can get access to the authenticated user during the boot process.

3 likes
marvanni's avatar

For the time being this works for me :

class MyController extends Controller 
{
    public function callAction($method, $parameters)
    {
        dd(app('auth')->user()); // this works

        return parent::callAction($method, $parameters);
    }
}

2 likes
sstringer's avatar

+1

I agree that it is desirable to be able to call and extend the Auth::user() from the constructor of the base controller. In my case, I have a master controller that is used by the majority of my site that adds some attributes to the user's permissions based...oh who cares? The point is that I need the user in the base controller.

Assuming this was changed for a reason, can anyone suggest a best-practices type of method to accomplish this? I saw the thing about sharing data with views, but that doesn't help me in my case. I'd like to avoid refactoring a core piece of my application if I don't have to.

Similar question: is there a good reason I shouldn't be accessing the Auth::user() in my base controller constructor?

1 like
zackcote's avatar

Also ran into this issue today, was very surprised I could no longer access Auth::user() in my controller's constructor.

arctic-ice-cool's avatar

I got here by looking for someone else with the problem that I am having.

I am unable to access a variable set in before middleware, in the __construct of a Controller. I was able to in 5.3. Has the middleware structure changed in 5.3 possibly?

Bounoable's avatar

Same problem here.. Can anyone tell me how I am supposed to share my user variable in my Controllers if I can't do this in the constructor? I did that in nearly every Controller I made, so I have to ensure that all of the Controllers have access to the user in the same way they've had it until now but I'm not having a clue how to do it right.

1 like
Francismori7's avatar

@Bounoable using Middlewares to share variables to your views is the recommended approach in most cases, because you don't have to extend the controller over and over again.

sstringer's avatar

@Francismori7 - Not to beat a dead horse here, but wouldn't the need to avoid writing logic over and over in every controller be precisely why you would want to put it in the parent controller's __construct() method? Middleware seems such an inefficient way to accomplish this as you'd have to handle the inclusion in your routes.

sstringer's avatar

All, there's an excellent thread getting into the technical bits here:

https://github.com/laravel/framework/issues/14699

@arctic-ice-cool - yes, middleware is now called after the controller is constructed.

Imo - I think this was a horrible decision. I understand it improves performance marginally, but it severely complicates things to lose this ability.

1 like
jekinney's avatar

Makes sense to me classes get booted while the request is sent instead of waiting for the request to get routed then boot the class.

edermcastro's avatar

Solved as follows.

use Illuminate\Support\Facades\Auth;

class CategController extends Controller
{
    protected $data = [];
    public function __construct(){
        //$this->data['config'] = ConfigModel::get();
        $this->middleware(function ($request, $next) { $this->data['user'] = Auth::user(); return $next($request); });
    }

    public function index(){
        return view('lists.categ',$this->data);
    }
}

In your view, call:

{{$user->field}} {{--ur field: email,name,id--}

Please or to participate in this conversation.