laravellaravel-breeze

Laravel File system auth


I try build a Laravel authentication application that is based on file system storage and in database based way parallel.

I made a method, like this:

    private function fileAuth(array $credentials): void
    {
        $userFileName = config('backup_values.backup_path') . $credentials['email'] . '.json';
        $user = AuthFileUtils::readFile($userFileName);
        if (Hash::check($credentials['password'], $user->password)) {
            $loggedInUser = new User();
            foreach ($user as $key => $value) {
                $loggedInUser->{$key} = $value;
            };
            Auth::guard('web')->login($loggedInUser);
        } else {
            RateLimiter::hit($this->throttleKey());
            throw ValidationException::withMessages([
                'email' => trans('auth.failed'),
            ]);
        }
    }

I try use Auth::guard('web')->login($loggedInUser) method but it call database query. Do I need create custom provider? How can I make it in a simply way? Please help me.


Solution

  • I made a custom provider and I registered it like this:

    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\Facades\Auth;
    use Illuminate\Support\Facades\Vite;
    use Illuminate\Support\ServiceProvider;
    
    class AppServiceProvider extends ServiceProvider
    {
        public function register(): void
        {
            //
        }
    
        public function boot(): void
        {
            Vite::prefetch(concurrency: 3);
    
            Auth::provider('custom', function ($app, array $config) {
                return new CustomUserProvider();
            });
        }
    }
    

    The custom provider looks like this:

    <?php
    
    namespace App\Providers;
    
    use App\Models\User;
    use App\utils\AuthFileUtils;
    use Illuminate\Contracts\Auth\Authenticatable;
    use Illuminate\Contracts\Auth\UserProvider;
    use Illuminate\Support\Facades\Hash;
    
    class CustomUserProvider implements UserProvider
    {
    
        public function retrieveById($identifier)
        {
    
        }
    
        public function retrieveByToken($identifier, #[\SensitiveParameter] $token)
        {
    
        }
    
        public function updateRememberToken(Authenticatable $user, #[\SensitiveParameter] $token)
        {
    
        }
    
        public function retrieveByCredentials(#[\SensitiveParameter] array $credentials)
        {
            $fileName = config('backup_values.backup_path') . $credentials['email'] . '.json';
            $userFromFile = AuthFileUtils::readFile($fileName);
            $user = new User();
            foreach ($userFromFile as $key => $value) {
                $user->$key = $value;
            }
            return $user;
        }
    
        public function validateCredentials(Authenticatable $user, #[\SensitiveParameter] array $credentials)
        {
            $result = Hash::check($credentials['password'], $user->getAuthPassword());
            return $result;
        }
    
        public function rehashPasswordIfRequired(Authenticatable $user, #[\SensitiveParameter] array $credentials, bool $force = false)
        {
            $result = $credentials['password'];
            return hash::make($result);
        }
    }
    

    And I set it in auth.php like this:

        'providers' => [
            'users' => [
                'driver' => 'custom',
                'model' => env('AUTH_MODEL', App\Models\User::class),
            ],
        ],
    
    

    But the user not logged in. How can I use it? The methods called in CustomUserProvider and I think result is good, but session not redirected to dashboard.