Auth::user() in controller construct

Published 2 years ago by golden

Hey guys! After updating from 5.2 to 5.3 I noticed that Auth::user() returns NULL to me when I call it in __construct() (but in action it return's user as always), wtf? I need to get user in controllers construct.

tomopongrac
RomainLanz
nate.a.johnson
InaniELHoussain

In Laravel 5.3, you can't access the session or authenticated user in your controller's constructor, since the middlware isn't runnig yet

here is it the solution

protected $user;

/**
 * Create a new controller instance.
 *
 * @return void
 */
public function __construct()
{
    $this->middleware(function ($request, $next) {
        $this->user= Auth::user();

        return $next($request);
    });
}
golden

Thanks for info guys!

Jaytee
Jaytee
2 years ago (105,255 XP)

Alternatively, you can define any method on your class that contains the authenticated user. Just not in the constructor.

testingtools.co@gmail.com

I am using laravel 5.4 and new to laravel, I always get a null, can anyone please help me on this for the same issue.

I have tried the above mentioned alternatives but yet I get a null..

santacruz

I just ran into this in the following scenario:

In the controller I am using the constructor to dependency inject a service class:

class ItemsController extends Controller
{
    protected $items;

    public function __construct(ItemService $items)
    {
        $this->items = $items;
    }

In the service class I need the authenticated user in multiple methods, this is why I am including the authenticated user object (next to injecting other dependencies) in the service classes constructor like this:

class ItemService
{
    protected $user;
    protected $other;

    public function __construct(OtherService $other)
    {
        $this->user = auth()->user();

        $this->other = $other;
    }

Unfortunately, this is not working, because of the changes in Laravel. This is pretty bad, because the breaking changes not only affect the controllers, but also dependency injected service classes.

Any suggestions/workarounds/solutions for this scenario? I know I can directly inject the service class in the controller methods, but this is very repetitive since all methods in the controller are using the service class...

mjeffe@gmail.com

@santacruz, I am working on a project with a similar architectures as you describe, and ran into the same issue. This may be too late for you, but it took me a while to figure this all out, so I hope it helps somebody. Here is how I solved it.

In my base controller class, I added a middleware defined as a closure:

   protected $service;
    
   protected function setService($class) {
        $this->middleware(function ($request, $next) use ($class) {
            $this->service = resolve($class);
            return $next($request);
        });
    }

All the middle ware does is set the service as an instance member. This allows the closure to be defined when the controller is instantiated, but delays running it until middleware is run, at which point Auth::user() is available. Note the PHP syntax for passing a parameter into the closure: use ($class).

Then in each controller (which extends the base controller), I "include" the service:

    use App\Services\MyFooService;

    public function __construct() {
        $this->setService(MyFooService::class);
    }

Note that in the middleware closure I am using Laravel's IOC to resolve the class. I have all of my services registered in an DomainServiceProvider. This is where the user is injected into my service objects:

    public function register() {
        $this->app->bind('App\Services\MyFooService', function ($app) {
            return new \App\Services\MyFooService(Auth::user());
        });
    }

There is no mention of the ability to define middleware as a closure under the middleware documentaion. I sumbled upon it under the controller documentation: https://laravel.com/docs/5.4/controllers#controller-middleware

jjamesschuler

I feel like an idiot, but I cannot figure out how to get he Auth::user() from the request

namespace Modules\Article\Http\Controllers\Admin;
    use Illuminate\Http\Request as Request;
    use Backpack\CRUD\app\Http\Controllers\CrudController;
   // VALIDATION: change the requests to match your own file names if you 
   need form validation
   use Modules\Article\Http\Requests\ArticleRequest as StoreRequest;
  use Modules\Article\Http\Requests\ArticleRequest as UpdateRequest;
  use Auth;
  use App\User;
  use App\Http\Controllers\Controller;

 class ArticleCrudController extends CrudController
 {
   public $user;
   public function __construct(Request $request)
     { 
    parent::__construct();
     
    $this->middleware(function ($request, $next) {
        $this->user= Auth::user()->settings;
       // $this->dbsetup($this->user);
        return $next($request);
    });

    $this->setup($this->user);


    /*
    |--------------------------------------------------------------------------
    | BASIC CRUD INFORMATION
    |--------------------------------------------------------------------------
    */
    $this->crud->setModel("Modules\Article\Models\Article");
    $this->crud->setRoute(config('backpack.base.route_prefix').'/news/article');
    $this->crud->setEntityNameStrings('article', 'articles');

I am using Backpack CRUD and I just need to set the database config values dynamically from the logged in user. I have seen MULTIPLE solutions, none of which I have been able to get to work successfully.

I have to set the database config values where the $this->setup function is located or it will not work...any help is GREATLY APPRECIATED..

or better yet, I really just need to set the 'User' connection config values for the whole request....maybe I am going about this incorrectly....it has happened before

jjamesschuler

I guess I should ask a different question... How can I set a database config value based on the Authorized user at runtime?

Please sign in or create an account to participate in this conversation.