Laravel: Injecting the authenticated user in one line

I f*cking hate writing code for just writing more code

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
}

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.

Image for post
Image for post

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.

Image for post
Image for post

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.

Image for post
Image for post

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.

Image for post
Image for post

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.

Image for post
Image for post

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.

Graphic Designer graduate. Full Stack Web Developer. Retired Tech & Gaming Editor.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store