SaidbakR
SaidbakR

Reputation: 13544

Laravel 5 Auth is non object in Controller construct

In app\Http\Controller there is a master controller class named Controller that all other controllers inherits. In any other controller the following code works fine:

class OtherController extends Controller{

   public function index(){
      dd(\Auth::user()->id);
   }
} 

However, in the Controller.php i.e the parent class, when I try to do something like that in the construct method I have got Trying to get property of non-object error:

class Controller extends BaseController {

    use AuthorizesRequests,
        DispatchesJobs,
        ValidatesRequests;
    public $foo = 'null';

    public function __construct() {
        $this->middleware('auth');
        dd(\Auth::user()->id);//Error is here.
        dd(\Route::getCurrentRoute()->action['controller']);

    }

}

How could I solve this issue?

Upvotes: 1

Views: 1845

Answers (2)

Conor Mancone
Conor Mancone

Reputation: 2030

Edit to add an actual answer

Try declaring this method and putting your code in it, before the parent::call_action() line:

public function callAction($method, $parameters)
{
    // Put your code right here

    // then do this last
    return parent::callAction($method, $parameters);
}

Taken from the bottom of this page. The short of it is that callAction is always called right before the destination method is called, but it is also called after the middleware runs, so you will be able to properly access your auth facade. In all likelihood whatever you were trying to do in the constructor will work as you wanted it to in this method.

Original Answer

It's been a bit since I've poked around in laravel 5.4, but if I recall correctly the middleware doesn't fire until after the controller constructor, which means that you specifically can't do what you are trying to do. The auth middleware doesn't populate the Auth facade with the logged in user until after the controller is constructed, but before the controller method is called (which is why your first example works).

I believe that this is the intended behavior, so it is unlikely to change.

The short of it is (unless someone more knowledgeable corrects me) that you will have to find another way to do whatever it is you are trying to do.

Edit to add

Indeed, this question makes it clear that my suspicions were correct. Middleware fires after the controller constructor, which means that you cannot access the logged in user inside the controller constructor. In retrospect this is obviously the case because one thing you can do from within the controller constructor is specify which middlewares the system should run. If the middleware had already run, then you wouldn't be able to do that. So the short of it is that you can't (practically) access the Auth facade from within the controller constructor. This is intentional on the part of the laravel team, so it won't change anytime soon. You will have to find another way to do it.

Upvotes: 7

Bilal Ahmed
Bilal Ahmed

Reputation: 4066

I have update my answer on the basis of your error... make sure on the top of file add use Illuminate\Support\Facades\Auth;

Now with laravel 4.2+ it is easy to get user's id:

$userId = Auth::id();

that is all.

But to retrieve user's data other than id, you use:

$email = Auth::user()->email;

For more details, check security part of the documentation

Upvotes: 2

Related Questions