Laravel: Injecting the authenticated user in one line
I f*cking hate writing code for just writing more code
TL;DR: Use the
auth
middleware and then type-hint theAuthenticatable
Contract in your Controller method. If you’re here for the magic, then keep reading!
When you work with authentication, Laravel tells you that the recommended way to get the authenticated user is to call the Authentication Guard, which can be made through the Auth
facade or the auth()
helper.
$user = Auth::user();
The Auth
facade is basically a way to get the Authentication Manager. If you have read my articles about Managers and Authentication, you will know this manager in particular handles all the different Authentication Guards, treated as drivers.
You can still retrieve the user authenticated without the middleware, though, but you will have manually point out which Guard you want to check.
public function show()
{
if (! Auth::guard('api')->check()) {
return 'You are unauthenticated';
}
// ...
}
If you want a more direct route, you can just call the Guard you need from the method signature and then try to retrieve the user — if it wasn’t authenticated you will receive null
. For example we can use the default Session Guard.
public function show(SessionGuard $guard)
{
if (! $user = $guard->user()) {
return 'You are unauthenticated';
} // ...
}
But it feels like always doing something else to do something else. There must be a way to make the authenticated User available without having to call the guard itself.
Yes, there is it.
Betcha did authenticate
This one is very easy. We can just simply call the Authenticatable interface. When we do, the Service Container will automatically resolve it. That’s it, you’re done.
public function show(Authenticatable $user)
{
// Do something with the user
}
Don’t use
Authenticatable $user = null
, because (at least in Controllers for Laravel 6.x) the user won’t be resolved even if authenticated.
This will work nicely as long you are using the Authenticate Middleware, since it needs to set the correct Guard where the authenticated user is, otherwise it will always try to retrieve it from the default one (which is web
):
Route::get('show', 'SomethingController@show')
->middleware('auth');
Alternatively, we can use it in the construct method of your controller.
public function __construct()
{
$this->middleware('auth');
}
That’s it, but… how the Service Container knows how to retrieve the authenticated user? When it’s pointed to the correct place?
Following the breadcrumbs of bindings
The Service Provider for Authentication binds the Athenticatable
contract to a Closure.

This allows the Service Container to call that closure everytime an Authenticatable
is asked for, which is the interface your Users must implement to be able to login and what not.
The call goes to the userResolver()
inside the Manager, which returns another Closure.

When the Authentication Manager is instanced, it automatically creates that default Closure, which calls the authenticated User inside the default Guard when not Guard name is issued to it — otherwise, it will look for that Guard and try to retrieve the User.

When the Authenticate
Middleware tries to authenticate the user, one of the Guards will hit. When that happens, it will instruct the Manager that it should use that Guard for all authentication/authorization purposes by default.

That shouldUse()
method sets the default driver, and it rewrites the User Resolver Closure for the default one. I suppose this is done to avoid the developer trying to restore the default resolver logic after a Guard hits.

With this, we are just using some code sugar to call the current authenticated user. If you need to check for another guard, you will need the Auth
facade, or directly the Guard instance you need, to retrieve that user in particular.