6

I can get the ID of the authenticated user like this:

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

Great it works, ... but I have a load of methods which need it and I want a cleaner way of adding it to the class as a whole,so I can just reference the $id in each method. I was thinking of putting it into the constructor, but as Auth::user is a static, I am making a mess of things and don't know how to do it.

Many thanks for your help !

Vince
  • 1,405
  • 2
  • 20
  • 33

4 Answers4

5

Laravel >= 5.3

you can't access the session or authenticated user in your controller's constructor because the middleware has not run yet.

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:

class UserController extends Controller {

    protected $userId;

    public function __construct() {

        $this->middleware(function (Request $request, $next) {
            if (!\Auth::check()) {
                return redirect('/login');
            }
            $this->userId = \Auth::id(); // you can access user id here
     
            return $next($request);
        });
    }
}
Community
  • 1
  • 1
Ali Sherafat
  • 3,506
  • 2
  • 38
  • 51
4

Instead of using the Facade you can inject the contract for the authentication class and then set the user ID on your controller. Like @rotvulpix showed you could put this on your base controller so that all child controllers have access to the user ID too.

<?php

namespace App\Http\Controllers;

use Illuminate\Contracts\Auth\Guard;

class FooController extends Controller
{
    /**
     * The authenticated user ID.
     *
     * @var int
     */
    protected $userId;

    /**
     * Construct the controller.
     *
     * @param  \Illuminate\Contracts\Auth\Guard  $auth
     * @return void
     */
    public function __construct(Guard $auth)
    {
        $this->userId = $auth->id();
    }
}

The guard has an id() method which returns void if no user is logged in, which is a little easier than having to go through user()->id.

Dwight
  • 12,120
  • 6
  • 51
  • 64
  • Yeah, read the upgrade docs for Laravel 5.3 here: https://laravel.com/docs/5.3/upgrade#upgrade-5.3.0 This issue is mentioned there, session is no longer available in the constructor. – Dwight Feb 22 '17 at 10:49
2

You can use Auth::user() in the whole application. It doesn't matter where you are. But, in response to your question, you can use the 'Controller' class present in your controllers folder. Add a constructor there and make the reference to the user ID.

<?php namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesCommands;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;

/* Don't forget to add the reference to Auth */
use Auth;

abstract class Controller extends BaseController {

    use DispatchesCommands, ValidatesRequests;

    function __construct() {
        $this->userID = Auth::user()?Auth::user()->id:null;
    }
}

Then, in any method of any controller you can use the $this->userID variable.

rotvulpix
  • 468
  • 3
  • 9
0

You could find your solution in the official documentation of Laravel by creating middleware in the constructor. Because, when the controller constructor was called, middleware was not running at that time. So, you need to run it in the constructor.

Here are the answer of your question: https://stackoverflow.com/a/76637345/5640381

Ketan Chaudhari
  • 329
  • 3
  • 7