33

So I am usually getting the current user using Auth::user() and when I am determining if a user is actually logged in Auth::check. However this doesn't seem to work in my AppServiceProvider. I am using it to share data across all views. I var_dump both Auth::user() and Auth::check() while logged in and I get NULL and false.

How can I get the current user inside my AppServiceProvider ? If that isn't possible, what is the way to get data that is unique for each user (data that is different according to the user_id) across all views. Here is my code for clarification.

if (Auth::check()) {
        $cart = Cart::where('user_id', Auth::user()->id);
        if ($cart) {
            view()->share('cart', $cart);

        }
    } else {
        view()->share('cartItems', Session::get('items'));
    }
Moppo
  • 18,797
  • 5
  • 65
  • 64
Codearts
  • 2,816
  • 6
  • 32
  • 54
  • 1
    You need to create a custom middleware for this, see the discussions: https://laracasts.com/discuss/channels/laravel/using-auth-in-service-provider-to-get-user-object, https://github.com/laravel/framework/issues/7906 – Burak May 22 '16 at 09:18

3 Answers3

63

Laravel session is initialized in a middleware so you can't access the session from a Service Provider, because they execute before the middleware in the request lifecycle

You should use a middleware to share your varibles from the session

However, If for some other reason you want to do it in a service provider, you can do it using a view composer with a callback, like this:

public function boot()
{
    //compose all the views....
    view()->composer('*', function ($view) 
    {
        $cart = Cart::where('user_id', Auth::user()->id);
        
        //...with this variable
        $view->with('cart', $cart );    
    });  
}

The callback will be executed only when the view is actually being composed, so middlewares will be already executed and session will be available

Moppo
  • 18,797
  • 5
  • 65
  • 64
  • Just a note, I tried doing this today (Laravel 5.4) and it would not work with a closure as indicated in this answer. Providing a class name to an external object, e.g. `view()->composer('*', \App\Http\ViewComposers\MyComposer::class)` was the only way I could get it to recognize `Auth::user()` as anything but `null`. – miken32 Aug 18 '18 at 21:33
  • how I can achieve same when using APIs as their are not blade/view used when using Laravel API's – Abhi Burk Jul 20 '20 at 06:02
  • yeah this approach worked for me – CG_DEV Feb 13 '22 at 03:08
  • Please have a look at **[this question](https://stackoverflow.com/q/71268103/4512005)** too. Thanks! – Razvan Zamfir Feb 28 '22 at 13:32
  • This is great It works for Laravel 9 too. – Maji Mazuri Jan 15 '23 at 11:15
17

In AuthServiceProvider's boot() function write these lines of code

public function boot()
{
    view()->composer('*', function($view)
    {
        if (Auth::check()) {
            $view->with('currentUser', Auth::user());
        }else {
            $view->with('currentUser', null);
        }
    });
}

Here * means - in all of your views $currentUser variable is available.

Then, from view file {{ currentUser }} will give you the User info if user is authenticated otherwise null.

Maniruzzaman Akash
  • 4,610
  • 1
  • 37
  • 34
  • I want to share my cart data to all pages , it's helped me lot – Risheekant Vishwakarma Dec 26 '18 at 07:29
  • Nice solution, although I'd suggest not putting in `AuthServiceProvider` as `boot()` should be limited to registering authentication and authorization services. Maybe `AppServiceProvider` or even `ComposerServiceProvider`? – simonw16 Mar 12 '19 at 19:47
  • how I can achieve same when using APIs as their are not blade/view used when using Laravel API's – Abhi Burk Jul 20 '20 at 06:02
  • @AbhiBurk in api, you've to definitely pass a token to get data. I'm not sure if that can be done in AppServiceProvider. – Maniruzzaman Akash Jul 20 '20 at 08:08
0

As per my Laravel 7 experience, Auth::user() does not work in AppServiceProvider.php instead the helper function auth()->user() did the trick for me.

public function boot()
    {

        if (auth()->check()) {
            View::composer('layout.app', function ($view) {
                $userName = auth()->user()->name;
                $view->with(['userName' => $userName]);
            });
        }
    }
Dinesh Suthar
  • 853
  • 1
  • 17
  • 41