Auth::user() in controller construct
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.
Hey @golden !
There is a discussion about it in the Laravel repository.
Another useful resource:
https://laravel-news.com/2016/08/controller-construct-session-changes-in-laravel-5-3/
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);
});
}
Thanks for info guys!
Alternatively, you can define any method on your class that contains the authenticated user. Just not in the constructor.
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..
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...
@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
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
I guess I should ask a different question... How can I set a database config value based on the Authorized user at runtime?
You can also declare function that contain Auth::user() in controller.php file
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function user()
{
return Auth::user();
}
}
and then you can use it in your controller like : $this->user()->id;
An alternative to load auth()->user() before any controller action is to extend Laravel callAction() inside your controller. It allows you to use auth()->user() and for example pass it to a protected property in your controller.
This seems to be available at least from Laravel 5.0 so is less limited than a middleware closure in constructor https://laravel.com/api/5.0/Illuminate/Routing/Controller.html#method_callAction
I found this in this Stackoverflow thread: https://stackoverflow.com/questions/34261796/before-executing-action-in-laravel-5-1
Please or to participate in this conversation.