How To Setup Multi Auth In Laravel : A Step By Step Guide

Do you need to manage multiple users with different types of guards in Laravel? This article will take you through the step-by-step of setting up multi-authentication with different types of users. Laravel has all it takes to grant users access to multiple application multi-users/admin. From this post, you will learn how to set up everything following a simple process. This is the best solution to creating flexible and strong authentication systems in Laravel



Install Laravel

To begin, make sure you have Laravel installed on your system. If not, you can install it using Composer by running the following command:
  
composer create-project --prefer-dist laravel/laravel laravelAuth
composer require laravel/breeze --dev


Create Additional Authentication Guards

To implement multi-authentication, we need to create additional guards for different user types. Let's say we want to create an admin guard alongside the default user guard. First, define the admin guard in the config/auth.php file:


    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'admin' => [
            'driver' => 'session',
            'provider' => 'admins',
        ],
       
    ],


Define Authentication Providers

After creating guards, define the corresponding authentication providers. In the same config/auth.php file, add the providers for users and admins:

  'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Models\Admin::class,
        ],
       
        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

Create Admin Model


Create Admin model similar user

    <?php

    namespace App\Models;

    use Illuminate\Contracts\Auth\MustVerifyEmail;
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Foundation\Auth\User as Authenticatable;
    use Illuminate\Notifications\Notifiable;
    use Laravel\Sanctum\HasApiTokens;

    class Admin extends Authenticatable
    {
        use HasApiTokens, HasFactory, Notifiable;

        protected $guard = 'admin';

        /**
         * The attributes that are mass assignable.
         *
         * @var array<int, string>
         */
        protected $fillable = [
            'name',
            'email',
            'password',
        ];

        /**
         * The attributes that should be hidden for serialization.
         *
         * @var array<int, string>
         */
        protected $hidden = [
            'password',
            'remember_token',
        ];

        /**
         * The attributes that should be cast.
         *
         * @var array<string, string>
         */
        protected $casts = [
            'email_verified_at' => 'datetime',
        ];
    }



Create Request


Create LoginRequest.php file under AdminAuth folder



    <?php

    namespace App\Http\Requests\Adminauth;

    use Illuminate\Auth\Events\Lockout;
    use Illuminate\Foundation\Http\FormRequest;
    use Illuminate\Support\Facades\Auth;
    use Illuminate\Support\Facades\RateLimiter;
    use Illuminate\Support\Str;
    use Illuminate\Validation\ValidationException;

    class LoginRequest extends FormRequest
    {
        /**
         * Determine if the user is authorized to make this request.
         *
         * @return bool
         */
        public function authorize()
        {
            return true;
        }

        /**
         * Get the validation rules that apply to the request.
         *
         * @return array
         */
        public function rules()
        {
            return [
                'email' => ['required', 'string', 'email'],
                'password' => ['required', 'string'],
            ];
        }

        /**
         * Attempt to authenticate the request's credentials.
         *
         * @return void
         *
         * @throws \Illuminate\Validation\ValidationException
         */
        public function authenticate()
        {
            $this->ensureIsNotRateLimited();

            if (! Auth::guard('admin')->attempt($this->only('email', 'password'), $this->boolean('remember'))) {
                RateLimiter::hit($this->throttleKey());

                throw ValidationException::withMessages([
                    'email' => trans('auth.failed'),
                ]);
            }

            RateLimiter::clear($this->throttleKey());
        }

        /**
         * Ensure the login request is not rate limited.
         *
         * @return void
         *
         * @throws \Illuminate\Validation\ValidationException
         */
        public function ensureIsNotRateLimited()
        {
            if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
                return;
            }

            event(new Lockout($this));

            $seconds = RateLimiter::availableIn($this->throttleKey());

            throw ValidationException::withMessages([
                'email' => trans('auth.throttle', [
                    'seconds' => $seconds,
                    'minutes' => ceil($seconds / 60),
                ]),
            ]);
        }

        /**
         * Get the rate limiting throttle key for the request.
         *
         * @return string
         */
        public function throttleKey()
        {
            return Str::lower($this->input('email')).'|'.$this->ip();
        }
    }


Create Admin Auth Controller


Copy Auth folder and create new Adminauth and replace this code 




Migrations


Copy the generated user table and create a new admin table, then replace the table name




Create Routes



Create admin auth route file for admin auth just copy this code

    <?php

    use App\Http\Controllers\Adminauth\AuthenticatedSessionController;
    use App\Http\Controllers\Adminauth\ConfirmablePasswordController;
    use App\Http\Controllers\Adminauth\EmailVerificationNotificationController;
    use App\Http\Controllers\Adminauth\EmailVerificationPromptController;
    use App\Http\Controllers\Adminauth\NewPasswordController;
    use App\Http\Controllers\Adminauth\PasswordResetLinkController;
    use App\Http\Controllers\Adminauth\RegisteredUserController;
    use App\Http\Controllers\Adminauth\VerifyEmailController;
    use Illuminate\Support\Facades\Route;

    Route::group(['middleware' => ['guest:admin'],'prefix'=>'admin','as'=>'admin.'],function(){

        Route::get('register', [RegisteredUserController::class, 'create'])
                    ->name('register');

        Route::post('register', [RegisteredUserController::class, 'store']);

        Route::get('login', [AuthenticatedSessionController::class, 'create'])
                    ->name('login');

        Route::post('login', [AuthenticatedSessionController::class, 'store']);

        Route::get('forgot-password', [PasswordResetLinkController::class, 'create'])
                    ->name('password.request');

        Route::post('forgot-password', [PasswordResetLinkController::class, 'store'])
                    ->name('password.email');

        Route::get('reset-password/{token}', [NewPasswordController::class, 'create'])
                    ->name('password.reset');

        Route::post('reset-password', [NewPasswordController::class, 'store'])
                    ->name('password.update');
    });

    Route::group(['middleware' => ['auth:admin'],'prefix'=>'admin','as'=>'admin.'],function(){
        Route::get('verify-email', [EmailVerificationPromptController::class, '__invoke'])
                    ->name('verification.notice');

        Route::get('verify-email/{id}/{hash}', [VerifyEmailController::class, '__invoke'])
                    ->middleware(['signed', 'throttle:6,1'])
                    ->name('verification.verify');

        Route::post('email/verification-notification', [EmailVerificationNotificationController::class, 'store'])
                    ->middleware('throttle:6,1')
                    ->name('verification.send');

        Route::get('confirm-password', [ConfirmablePasswordController::class, 'show'])
                    ->name('password.confirm');

        Route::post('confirm-password', [ConfirmablePasswordController::class, 'store']);

        Route::post('logout', [AuthenticatedSessionController::class, 'destroy'])
                    ->name('logout');
    });



Preview 




Source Code :

https://github.com/BugBlitz98/laravel-multi-auth

Congratulations! You have successfully created a multi-authentication feature in your Laravel application. Your system has more flexibility to handle different users having different authentication guards, making your application more secure and user-friendly. Do as many tests with different configurations as possible before finally customizing one that will meet your exact needs. Happy coding!

5 Comments

Post a Comment
Previous Post Next Post