Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Laravel Cache Auth::user(). Learn how to cache the logged in user at https://paulund.co.uk/laravel-cache-authuser
<?php
namespace App\Providers;
use App\Models\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
User::observe(UserObserver::class);
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
// Config/auth.php
'providers' => [
'users' => [
'driver' => 'cache-user',
'model' => App\Models\User::class,
]
]
<?php
namespace App\Providers;
use App\Auth\CacheUserProvider;
use Illuminate\Support\Facades\Auth;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
// Caching user
Auth::provider('cache-user', function() {
return resolve(CacheUserProvider::class);
});
}
}
<?php
namespace App\Auth;
use App\Models\User;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Support\Facades\Cache;
/**
* Class CacheUserProvider
* @package App\Auth
*/
class CacheUserProvider extends EloquentUserProvider
{
/**
* CacheUserProvider constructor.
* @param HasherContract $hasher
*/
public function __construct(HasherContract $hasher)
{
parent::__construct($hasher, User::class);
}
/**
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
return Cache::get("user.$identifier") ?? parent::retrieveById($identifier);
}
}
<?php
namespace App\Observers;
use Illuminate\Foundation\Auth\User;
use Illuminate\Support\Facades\Cache;
/**
* User observer
*/
class UserObserver
{
/**
* @param User $user
*/
public function saved(User $user)
{
Cache::put("user.{$user->id}", $user, 60);
}
/**
* @param User $user
*/
public function deleted(User $user)
{
Cache::forget("user.{$user->id}");
}
/**
* @param User $user
*/
public function restored(User $user)
{
Cache::put("user.{$user->id}", $user, 60);
}
/**
* @param User $user
*/
public function retrieved(User $user)
{
Cache::add("user.{$user->id}", $user, 60);
}
}
@hongminhbka

This comment has been minimized.

Copy link

@hongminhbka hongminhbka commented Jul 26, 2018

I run with laravel version 5.5?
errror not found cache-user driver?
Help me! Thanks!

@AKopelevich

This comment has been minimized.

Copy link

@AKopelevich AKopelevich commented Sep 19, 2018

First of all, thanks for the terrific piece of code! ♥️

Happens that there is no code to actually store the "user.$identifier" key in the Cache.

I had to change the retrievedById method like this:

    public function retrieveById($identifier)
    {
        return Cache::remember('user.' . $identifier, 360, function () use ($identifier) {
            return parent::retrieveById($identifier);
        });
    }
@joao-pedro-alves

This comment has been minimized.

Copy link

@joao-pedro-alves joao-pedro-alves commented Dec 13, 2018

For some reason when I implement this technique all my responses take like 5 segs to finish even without executing any query!

A made a debug and i realized that this line parent::__construct($hasher, User::class); in CacheUserProvidercauses the problem. When I comment it the response time gets back to the normal but the auth cache stops working...

I couldn't find any solution...

@AKopelevich

This comment has been minimized.

Copy link

@AKopelevich AKopelevich commented Jan 14, 2019

For some reason when I implement this technique all my responses take like 5 segs to finish even without executing any query!

A made a debug and i realized that this line parent::__construct($hasher, User::class); in CacheUserProvidercauses the problem. When I comment it the response time gets back to the normal but the auth cache stops working...

I couldn't find any solution...

@joao-pedro-alves Did you correctly import the HasherContract?
use Illuminate\Contracts\Hashing\Hasher as HasherContract;

@frankinedinburgh

This comment has been minimized.

Copy link

@frankinedinburgh frankinedinburgh commented Sep 18, 2019

It fails to reach retrieveById for me with the above code. I'm using laravel 5.3. It loads the cache-user provider but queries the db for the user each time i make a request. Any ideas what I could be doing wrong ?

@paulund

This comment has been minimized.

Copy link
Owner Author

@paulund paulund commented Sep 18, 2019

@frankinedinburgh I use this on Laravel 5.5 it might do the eloquent user providers differently.

@frankinedinburgh

This comment has been minimized.

Copy link

@frankinedinburgh frankinedinburgh commented Sep 19, 2019

@paulund Even after upgrading to 5.5 I still am unable to get the above to cache or call retrieveById

@paulund

This comment has been minimized.

Copy link
Owner Author

@paulund paulund commented Sep 23, 2019

@frankinedinburgh not sure, this is the same setup as I'm using and it's hitting cache on mine. I'll try turning this into a package you can just install hopefully that will help.

@wenzhan510

This comment has been minimized.

Copy link

@wenzhan510 wenzhan510 commented Jan 29, 2020

Thanks for writing this! It's really helpful and inspiring.

About a couple months ago I was looking for one to cache auth user model and jumped into this. However, when I apply it to my project it initially did not work as expected. My cached user model is only achieved during guest login, but not for those already logged users. btw I used laravel 5.7 not sure if it is because of this.

After some time I figured out that apart from retrieveById, there's the retrieveByToken function that may also needs override, so that after logging with credentials, cached user model can still be retrieved by the Auth facade, via session token.

If others run into the same issue, I've written down what I did on laravel 5.7 here: https://github.com/lyn510/laravel-auth-user

@janzankowski

This comment has been minimized.

Copy link

@janzankowski janzankowski commented Mar 11, 2020

I have a question: when using this, how can I make sure to skip the cache when I really need to get the user from the DB? Will User::find($id) do it? I suspect it will, but need to make sure.

@paulund

This comment has been minimized.

Copy link
Owner Author

@paulund paulund commented Mar 14, 2020

Hi @janzankowski this shouldn't be used for fetching users, this method is used to stop making calls to the database when the user has logged into your application.

@wakjoko

This comment has been minimized.

Copy link

@wakjoko wakjoko commented Apr 22, 2020

hi @paulund,

big applause for your idea on caching logged in user. i've got it working & it works like charm. thanks again.

and i wanted to share a bit of modification on user observer, to invalidate the cached user when the user is updating their profile.
so in case anyone stuck on getting the cache not being refreshed after a user updated their profile, here's my user observer.

<?php
namespace App\Observers;

use Illuminate\Foundation\Auth\User;
use Illuminate\Support\Facades\Cache;

class CacheLoggedInUserObserver
{
    public function saved(User $user)
    {
        $this->deleted($user);

        Cache::remember("user.{$user->id}", 60, function () use ($user) {
            return $user;
        });
    }

    public function deleted(User $user)
    {
        Cache::forget("user.{$user->id}");
    }

    public function restored(User $user)
    {
        $this->saved($user);
    }

    public function retrieved(User $user)
    {
        $this->saved($user);
    }
}
@dipenparmar12

This comment has been minimized.

Copy link

@dipenparmar12 dipenparmar12 commented Sep 6, 2020

CacheUserProvider.php

Line number 31 should be.

    public function retrieveById($identifier)
    {
        return \Cache::get("user.$identifier") ?? parent::retrieveById($identifier);
    }
@dipenparmar12

This comment has been minimized.

Copy link

@dipenparmar12 dipenparmar12 commented Sep 6, 2020

CacheUserProvider
Line number 31 should be.

    /**
     * @param mixed $identifier
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveById($identifier)
    {
        return Cache::get("user.$identifier") ?? parent::retrieveById($identifier); // here little Type
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment