Laravel 5: Global Auth $user variable in all controllers
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Globalizing Authentication: Accessing the $user Across All Laravel Controllers
As developers working within the Laravel ecosystem, we constantly strive for cleaner, more DRY (Don't Repeat Yourself) code. One of the most common bottlenecks we encounter is repetitive setup logic, especially when dealing with authenticated users. You’ve correctly identified a common desire: how can we make the currently logged-in $user object available to every controller method without cluttering every single file with use Auth; and Auth::user() calls?
Let's dive into why your attempt with the __construct failed, and explore the robust, idiomatic Laravel solutions for achieving this global availability.
The Pitfall of Constructor Injection in Controllers
You attempted to inject the user data into your base controller's constructor:
public function __construct()
{
$user = Auth::user();
View::share('user', $user); // This only affects views, not other controllers!
}
While this pattern works perfectly for sharing data with views (using View::share), it does not make the $user variable available directly as a property or method within the controller class itself. Controllers are designed to be stateless request handlers. When you try to access $user in another controller, PHP simply doesn't know where that variable is defined unless you explicitly define it globally or use a mechanism like Dependency Injection.
This approach fails because controllers don't inherit state directly from the constructor in a way that persists across unrelated requests. We need a mechanism that hooks into the request lifecycle cleanly.
Solution 1: The Idiomatic Laravel Approach – Route Model Binding
The most "Laravel" way to handle authenticated user data is to let the routing system handle the injection, rather than forcing it into the controller's constructor. This leverages Laravel's powerful Eloquent relationships and service container.
If you are dealing with a specific resource (e.g., fetching a user profile), Route Model Binding automatically handles fetching the correct model based on the route parameters, making your controller methods incredibly clean.
In your UsersController, instead of manually calling Auth::user(), you let Laravel handle it:
use App\Models\User;
use Illuminate\Http\Request;
class UsersController extends Controller
{
public function index(User $user) // Laravel automatically resolves the authenticated user if configured correctly via middleware
{
// If using middleware that binds Auth::user() to a parameter:
$authUser = $user;
// Or, more commonly, you still access it explicitly if not bound directly:
$authenticatedUser = auth()->user();
$users = DB::table('users')
->where('user_id', $authenticatedUser->user_id)
->get();
return view('pages.users.index', compact('users'));
}
}
While this doesn't make $user a class property, it ensures that every controller method explicitly requests the necessary data based on the authenticated state, adhering to SOLID principles and keeping controllers focused purely on handling HTTP requests. For deep dives into Eloquent relationships, understanding how Laravel manages these bindings is crucial (see resources on Laravel documentation for advanced model usage).
Solution 2: Creating a Global Service or Trait for Shared Context
If you absolutely require a globally accessible property within all controllers—perhaps for debugging or logging purposes that spans the entire request scope—the best approach is to centralize this logic into a trait or a dedicated service class. This keeps your base controller clean while providing a controlled access point.
Here is how you can implement a BaseController that provides easy access:
app/Traits/UserAware.php
namespace App\Traits;
use Illuminate\Support\Facades\Auth;
trait UserAware
{
/**
* Get the currently authenticated user object.
* This method is available in all classes using this trait.
*/
public function getAuthenticatedUser()
{
return Auth::user();
}
}
app/Http/Controllers/BaseController.php
namespace App\Http\Controllers;
use App\Traits\UserAware; // Import the trait
class BaseController
{
use UserAware; // Use the trait
// You can add other shared methods here...
}
Now, any controller extending BaseController gains access to $this->getAuthenticatedUser() everywhere. This is cleaner than relying on static calls or trying to inject variables into a constructor that doesn't persist state across requests.
Conclusion
While the desire for a single global variable like $user in every controller is understandable, it often signals an architectural opportunity rather than a simple feature request. For accessing authenticated user data, we favor Laravel’s built-in mechanisms: Route Model Binding for clean resource fetching and Traits/Services for managing shared, non-request-specific logic. By adopting these patterns, you ensure your code remains maintainable, testable, and scalable, which is the hallmark of high-quality Laravel development (as emphasized in best practices found on Laravel documentation).