Multiple Authentication System Using Guards in Laravel

Multi-Auth System with Blade Templating in Laravel 6

Laravel LTS version 6.x came up with new and modified some of features. Auth system modified in this version with “ui vue –auth”.

In this learning, we will build multiple platforms and each platform will have its own login system or login panel, for instance, there will be a client panel and client will login from frontend and another panel will be for admin and they will login from backend. Admin will be able to create, update, delete and access some reports and they will have totally different platform. Moreover, each login panel will redirect its own panel after success login or fail login by using “RedirectIfAuthenticated” middleware.

Let’s start to create multiple login panels for client and admin using guards.

Step 1:

Create new Laravel project

Requirements for Laravel 6.x version installation:

   Composer 1.9.0

   PHP 7.2.0

   BCMath PHP Extension

   Ctype PHP Extension

   JSON PHP Extension

   Mbstring PHP Extension

   OpenSSL PHP Extension

   PDO PHP Extension

   Tokenizer PHP Extension

   XML PHP Extension

Download Laravel installer using composer:

composer global require Laravel/installer
Code language: PHP (php)

Create new Laravel project using composer after installing Laravel installer.

larvae new project_nameCode language: JavaScript (javascript)

for me

laravel new multi_authsCode language: JavaScript (javascript)

 Step 2:

Create database and connect with the project:

CREATE DATABASE database_name

 for me

CREATE DATABASE multipleauths

 Connect the database with the project: 

Project’s root directory and open .env file and edit it:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=multiauths
DB_USERNAME=root
DB_PASSWORD=

 Step 3:

Create migration for admin and client table

php artisan make:migration create_admins_table
php artisan make:migration create_clients_tableCode language: CSS (css)

Open “admins” from database/migrations and put the following code of “up” method:

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::create('admins', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->integer('role')->default(1);
        $table->rememberToken();
        $table->timestamps();
    });
}Code language: PHP (php)

Open “clients” from database/migrations and put the following code of “up” method:

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::create('clients', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->integer('role')->default(1);
        $table->rememberToken();
        $table->timestamps();
    });
}Code language: PHP (php)

 Now before migrating we need to fix our memory and for that open “AppServiceProvider.php” from app/Providers and put the following line in to boot() method: 

Now use migration command for migrating 

php artisan migrate

 Step 4: 

Create models for admin and cline in a Model folder and put necessary attributes.

Create models:

php artisan make:model Models\Admin
php artisan make:model Models\ClientCode language: CSS (css)

 Open Admin.php from app/Models and put the following code in the model:

<?php
 
namespace App\Models;
 
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticate;
 
class Admin extends Authenticate
{
    use Notifiable;
 
    protected $guard = 'admin';
 
    protected $fillable = [
        'name', 'email', 'password',
    ];
 
    protected $hidden = [
        'password', 'remember_token',
    ];
}Code language: HTML, XML (xml)

Again open Client.php from app/Models and put the following code in the model:

<?php
 
namespace App\Models;
 
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticate;
 
class Client extends Authenticate
{
    use Notifiable;
 
    protected $guard = 'client';
 
    protected $fillable = [
        'name', 'email', 'password',
    ];
 
    protected $hidden = [
        'password', 'remember_token',
    ];
}Code language: HTML, XML (xml)

 Step 5:

Create guard for both admin and client

Open auth.php from config folder and in the “guards” block add two guards admin and client respectively and it is as follows: 

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
 
    'api' => [
        'driver' => 'token',
        'provider' => 'users',
        'hash' => false,
    ],
 
    'admin' => [
        'driver' => 'session',
        'provider' => 'admins',
    ],
 
    'client' => [
        'driver' => 'session',
        'provider' => 'clients',
    ],
 
 
],Code language: PHP (php)

As we mentioned in the guards block that, providers admins and clients so now we need to create those providers in the “providers” block where we will filter our two models Admin and Client so those providers will help Laravel to use those models for authentication or validation while we will be using those guards.

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\User::class,
    ], 
 
    'admins' => [
        'driver' => 'eloquent',
        'model' => App\Models\Admin::class,
    ],
 
    'clients' => [
        'driver' => 'eloquent',
        'model' => App\Models\Client::class,
    ],
 
 
],Code language: PHP (php)

 Step 6:

Create login for admin and client in the app/Http/Controllers/Auth/LoginController.php

Here, we need to mention our created guards through middleware in the supper method __construct()

/**
 * Create a new controller instance.
 *
 * @return void
 */
public function __construct()
{
    $this->middleware('guest')->except('logout');
    //Add these following lines
    $this->middleware('guest:admin')->except('logout');
    $this->middleware('guest:client')->except('logout');Code language: PHP (php)

 We need login pages and  loginCheck methods for both admin and client and these are as follows:

use Illuminate\Support\Facades\Auth; //Import Auth
 
 
public function showAdminLoginForm()
{
    return view('auth.login', ['url' => 'admin']);
}
 
public function adminLogin(Request $request)
{
    $this->validate($request, [
        'email'   => 'required|email',
        'password' => 'required|min:6'
    ]);
 
    if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) {
 
        return redirect()->intended('/admin');
    }
    return back()->withInput($request->only('email', 'remember'));
}
 
 
public function showClientLoginForm()
{
    return view('auth.login', ['url' => 'client']);
}
 
public function clientLogin(Request $request)
{
    $this->validate($request, [
        'email'   => 'required|email',
        'password' => 'required|min:6'
    ]);
 
    if (Auth::guard('client')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) {
 
        return redirect()->intended('/client');
    }
    return back()->withInput($request->only('email', 'remember'));
}Code language: PHP (php)

 Step 7:

Create Registration method in the app/Http/Controllers/Auth/RegisterController.php

First we will import two models in this controller

use App\Models\Admin;
use App\Models\Client;Code language: PHP (php)

 Then for both created guards need to add middleware in the constructor 

/**
 * Create a new controller instance.
 *
 * @return void
 */
public function __construct()
{
    $this->middleware('guest');
      // add these following lines
    $this->middleware('guest:admin');
    $this->middleware('guest:client');
}Code language: PHP (php)

 Now it is ready to create register form and create methods for both admin and client:

Admin model will be using to create admin user and we will send url as ‘admin’ to the view because this way it will be dynamic url so we will be handling our register from with one view. However, in the same way client user will be created.

/**
 * @return Factory|View
 */
public function showAdminRegisterForm()
{
    return view('auth.register', ['url' => 'admin']);
}
 
/**
 * @param Request $request
 *
 * @return RedirectResponse
 */
protected function createAdmin(Request $request)
{
    $this->validator($request->all())->validate();
    Admin::create([
        'name' => $request->name,
        'email' => $request->email,
        'password' => Hash::make($request->password),
    ]);
    return redirect()->intended('login/admin');
}
 
 /**
 * @return Factory|View
 */
public function showClientRegisterForm()
{
    return view('auth.register', ['url' => 'client']);
}
 
/**
 * @param Request $request
 *
 * @return RedirectResponse
 */
protected function createClient(Request $request)
{
    $this->validator($request->all())->validate();
    Client::create([
        'name' => $request->name,
        'email' => $request->email,
        'password' => Hash::make($request->password),
    ]);
    return redirect()->intended('login/client');
}Code language: PHP (php)

 Step 8:

All necessary steps are done to run commands for creating new auth in Laravel 6.x version.

Before or older version Laravel it was just “php artisan make:auth” to create auth but earlier LTS version 6.x Laravel came up with new auth with “ui vue” as follows:

composer require laravel/ui --dev 
php artisan ui vue –auth
npm install && npm run devCode language: JavaScript (javascript)

 Step 9:

Create AdminController and ClientController

php artisan make:controller AdminController
php artisan make:controller ClientControllerCode language: CSS (css)

 Open app/Http/Controllers/AdminController and put the follow code where we are using our created guard “admin” in our constructor so only admin guard user can access this controller’s methods or views.

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
 
class AdminController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:admin');
    }
 
    /*
     * After logging as client the dashboard for client
     * @return \Illuminate\Contracts\Support\Referable
     * */
    public function adminDashboard()
    {
        return view('admin.dashboard');
    }
}Code language: HTML, XML (xml)

 And open app/Http/Controllers/ClientController and put the follow code where again we are using our created “client” guard in the constructor.

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
 
class ClientController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:client');
    }
 
    /*
     * After logging as client the dashboard for client
     * @return \Illuminate\Contracts\Support\Referable
     * */
    public function clientDashboard()
    {
        return view('client.dashboard');
    }
}Code language: HTML, XML (xml)

BLADE TEMPLATING STRUCTURE 

In blade, we can make different sections for our templating which is very useful to reuse code and different layouts or theming. It is showing below that, how to create blade templating with different sections and there is possibility to include some other layouts. 

Step 10: 

Create all views we called in our controllers 

       Create two directory in resource/views/admin and resource/views/client

  • Create resource/views/layouts/master_auth.blade.php (please add your html, head, title tags)
<body>
<div id="app">
    <nav class="navbar navbar-expand-md navbar-light navbar-laravel">
        <div class="container">
            <a class="navbar-brand" href="/{{ url('/') }}">
                Multiple Auths
            </a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                <span class="navbar-toggler-icon"></span>
            </button>
 
            <div class="collapse navbar-collapse" id="navbarSupportedContent">
                <!-- Left Side Of Navbar -->
                <ul class="navbar-nav mr-auto">
 
                </ul>
 
                <!-- Right Side Of Navbar -->
                <ul class="navbar-nav ml-auto">
                    <!-- Authentication Links -->
                    <li class="nav-item dropdown">
                        <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                            Hi There <span class="caret"></span>
                        </a>
 
                        <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                            <a class="dropdown-item" href="/{{ route('logout') }}"
                               onclick="event.preventDefault();
                                                 document.getElementById('logout-form').submit();">
                                {{ __('Logout') }}
                            </a>
 
                            <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
                                @csrf
                            </form>
                        </div>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
 
    <main class="py-4">
        @yield('content')
    </main>
</div>
</body>Code language: HTML, XML (xml)

 Create resource/views/admin/dashboard.blade.php and put the following code where we are going to use our created “master_auth” template:

@extends('layouts.master_auth')
 
@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Dashboard</div>
 
                    <div class="card-body">
                        Hi Admin!
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsectionCode language: HTML, XML (xml)

 Create resource/views/client/dashboard.blade.php which extends our “master_auth” template and put the following code:

@extends('layouts.master_auth')
 
@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Dashboard</div>
 
                    <div class="card-body">
                        Hi client!
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsectionCode language: HTML, XML (xml)

 Create resource/views/welcome.blade.php and put the following code (please add your html, head, title and body tags):

<body>
        <div class="flex-center position-ref full-height">
            @if (Route::has('login'))
                <div class="top-right links">
                    @auth
                        <a href="/{{ url('/home') }}">Home</a>
                    @else
                        <a href="/{{ route('login') }}">Login</a>
 
                        @if (Route::has('register'))
                            <a href="/{{ route('register') }}">Register</a>
                        @endif
                    @endauth
                </div>
            @endif
 
            <div class="content">
                <div class="title m-b-md">
                    Multiple Auths System
                </div>
 
                <div class="links">
                    <a href="/{{route('admin_register')}}">Admin Register</a>
                    <a href="/{{route('admin_login')}}">Admin Login</a>
                    <a href="/{{route('client_register')}}">Client Register</a>
                    <a href="/{{route('client_login')}}">Client Login</a>
                    <a href="/{{route('login')}}">User Register</a>
                    <a href="/{{route('register')}}">User Login</a>
                </div>
            </div>
        </div>
    </body>Code language: HTML, XML (xml)

 Step 11:

Create route for admin, client register, login methods and all routes

Route::view('/', 'welcome');
Auth::routes();
 
//********************************GET********************************
//LoginController
Route::get('/login/admin', 'Auth\LoginController@showAdminLoginForm')->name('admin_login');
Route::get('/login/client', 'Auth\LoginController@showClientLoginForm')->name('client_login');
 
//RegisterController
Route::get('/register/admin', 'Auth\RegisterController@showAdminRegisterForm')->name('admin_register');
Route::get('/register/client', 'Auth\RegisterController@showClientRegisterForm')->name('client_register');
 
//ClientController
Route::get('/client', 'ClientController@clientDashboard')->name('client_dashboard');
 
//AdminController
Route::get('/admin', 'AdminController@adminDashboard')->name('admin_dashboard');
 
//HomeController
Route::get('/home', 'HomeController@index')->name('home');
 
//********************************POST********************************
//LoginController
Route::post('/login/admin', 'Auth\LoginController@adminLogin')->name('admin_login');
Route::post('/login/client', 'Auth\LoginController@clientLogin')->name('client_login');
 
//RegisterController
Route::post('/register/admin', 'Auth\RegisterController@createAdmin')->name('admin_register');
Route::post('/register/client', 'Auth\RegisterController@createClient')->name('client_register');Code language: PHP (php)

Step 12:

Redirect after login according to login panel

so for this purpose we might get some problem after login and to solve this problem we can put the following code into RedirectIfAuthenticated.php middleware. However, open app/Http/Middleware/RedirectIfAuthenticated.php and put folowing code

<?php
namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Support\Facades\Auth;
 
class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if ($guard == "admin" && Auth::guard($guard)->check()) {
            return redirect('/admin');
        }
 
        if ($guard == "client" && Auth::guard($guard)->check()) {
            return redirect('/client');
        }
 
 
 
        if (Auth::guard($guard)->check()) {
            return redirect('/home');
        }
 
        return $next($request);
    }
}Code language: HTML, XML (xml)

 Step 13:

Modifying the exception handler, open app/Exceptions/Handler.php and put the following code:

<?php
 
namespace App\Exceptions;
 
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Auth\AuthenticationException;
use Auth;
class Handler extends ExceptionHandler
{
    protected function unauthenticated($request, AuthenticationException $exception)
    {
        if ($request->expectsJson()) {
            return response()->json(['error' => 'Unauthenticated.'], 401);
        }
        if ($request->is('admin') || $request->is('admin/*')) {
            return redirect()->guest('/login/admin');
        }
 
        if ($request->is('client') || $request->is('client/*')) {
            return redirect()->guest('/login/client');
        }
 
 
        return redirect()->guest(route('login'));
    }
}Code language: HTML, XML (xml)

 Step 14:

Finally we are done with all steps now we need to generate the key and run the project

For that we need to run two commands and those are as follows:

php artisan key:generate
php artisan serveCode language: CSS (css)

Hope this will help to understand Laravel multi auth system. To learn about multi auth systems in Laravel 9, check out this link. You can leave comments below for any help or confusion. I will try to address those as soon possible. Also, you can contact iXora Solution Laravel Team for any assistance on your project implementation at Contact-iXoraLaravel 

Add a Comment

Your email address will not be published. Required fields are marked *