Laravel-10 MultiAuth with JetStream and Livewire — Creating User and Admin portions (Part-1)

Mursaleen Ahmad
7 min readJul 21, 2023

--

Hello!
Today we will implement multiauth in Laravel-10 using Jetstream and Livewire.

By the way I’ll be using Laravel v10.14.1

Step 1: Installing Jetstream and Livewire

First of all for installing Jetstream navigate to your laravel project folder and run this command in your terminal

composer require laravel/jetstream

After it is successfully installed we move on to install Livewire with following command.

php artisan jetstream:install livewire

After Livewire is successfully installed you may see the message indicating to run following command in your terminal.

npm install && npm run dev

And in order to run the above command you need Node.js installed on your system. So after installing Node.js you can run that command in your terminal.

STEP 2: Setup database and run migrations

So now we have Jetstream installed we need to first setup the database and run migrations before we run our project in the browser.

So in order to setup the database we will use sqlite (You can use MySQL as well).

So first we will create our database.sqlite file by following command in your terminal.

touch database/database.sqlite

After that we need to make changes to the configuration file named .env

Go to .env file and search for this code:

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

And replace it with

DB_CONNECTION=sqlite

After that run migrations with this command

php artisan migrate

After the migrations ran successful you’d need to use php artisan serve command or you can start XAMPP’s Apache server and access your folder from htdocs

After opening your project in browser you’ll notice Login and Register button on top-right corner.

So now we have successfully installed a basic Login and Registration Package in our project.

STEP 3: Admin Controller and Model

Now we will create the Admin model and controller for handling the logic for our admin users.

For that first of all we make controller

php artisan make:controller AdminController

And then create model.

php artisan make:model Admin -m

So this admins table will be just like the users table so I can copy and paste the fields from users migration file to the admins migration file.

    public function up(): void
{
Schema::create('admins', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->foreignId('current_team_id')->nullable();
$table->string('profile_photo_path', 2048)->nullable();
$table->timestamps();
});
}

And our Admin model will also be similar to the User model, so I can copy and paste the User model file code into Admin model file and the only change I need to make is to modify

class User extends Authenticatable
to
class Admin extends Authenticatable

After these changes we just migrate our files again.

php artisan migrate

STEP 4: Seeding data to Admin and User table

We will create a new Factory for our Admin. So in order to make a new Factory run this command.

php artisan make:factory AdminFactory

copy and paste this code into AdminFactory.php file

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Admin>
*/
class AdminFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => 'Admin',
'email' => 'admin@gmail.com',
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
'profile_photo_path' => null,
'current_team_id' => null,
];
}
}

And then after that go to DatabaseSeeder.php file and modify the run() function as follows

    public function run(): void
{
\App\Models\Admin::factory()->create();
}

And then run following command

php artisan migrate --seed

After running command successfully you can see the admin user created inside the database successfully !

STEP 5: Creating Guard for Admin table

So for creating the guard for Admin we need to go to config/auth.php file

At its core, Laravel’s authentication facilities are made up of “guards” and “providers”. Guards define how users are authenticated for each request. For example, Laravel ships with a session guard which maintains state using session storage and cookies.

So in auth.php file we need to make some changes in different locations.

First of all we need to add a new guard like this.

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

Then add a provider for admins (provider name specified in guard)

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

// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],

Then add admins section in passwords,

    'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_reset_tokens',
'expire' => 60,
'throttle' => 60,
],
'admins' => [
'provider' => 'admins',
'table' => 'password_reset_tokens',
'expire' => 60,
'throttle' => 60,
],
],

After this we are done editing the auth.php file

Now we move on further :)

Now open up the file /app/Providers/FortifyServiceProvider.php and update the register() function as follows

Add these lines on top:

use App\Http\Controllers\AdminController;
use Laravel\Fortify\Actions\AttemptToAuthenticate;
use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Support\Facades\Auth;

And then update your register() function:

    public function register(): void
{
$this->app->when([AdminController::class,AttemptToAuthenticate::class,RedirectIfTwoFactorAuthenticatable::class])
->needs(StatefulGuard::class)
->give(function (){
return Auth::guard('admin');
});
}

Now go to vendor/laravel/framework/src/Illuminate/Contracts/Auth/StatefulGuard.php file and copy everyting (Ctrl+A then Ctrl+C)

Then go to app folder and create a new folder named Guards and create a new file named AdminStatefulGuard.php and paste that code here (Ctrl+V).

After pasting the code change the namespace line.

 namespace App\Guards;

STEP 6: Update AdminController

Now open up this file “vendor/laravel/fortify/src/Http/Controllers/AuthenticatedSessionController.php”

Copy everything and paste it into app/Http/Controllers/AdminController.php file.

After that we need to make 2 changes.

First keep the original namespace.

Means replace the “namespace Laravel\Fortify\Http\Controllers;” with

namespace App\Http\Controllers;

And replace “class AuthenticatedSessionController extends Controller” with

class AdminController extends Controller

Add a new route for admin in web.php file like this

use App\Http\Controllers\AdminController;



Route::group(['prefix'=>'admin','middleware'=>['admin:admin']],function(){
Route::get('/login', [AdminController::class, 'loginForm']);
Route::post('/login', [AdminController::class, 'store'])->name('admin.login');
});



Route::middleware(['auth:sanctum,admin', 'verified'])->get('/admin/dashboard', function () {
return view('dashboard');
})->name('dashboard');

Now add this loginForm() function to the AdminController.php file

    public function loginForm(){
return view('auth.login',['guard' => 'admin']);
}

And then update the resources/views/auth/login.blade.php file’s <form> line as follows.

<form method="POST" action="{{ isset($guard) ? url($guard.'/login') :  route('login') }}">

Now go to the path /vendor/laravel/fortify/src/Actions folder and copy two files from here

1- AttemptToAuthenticate.php
2- RedirectIfTwoFactorAuthenticatable.php

And the paste them in /app/Actions/Fortify/

Now open both files and change their namespaces to

namespace App\Actions\Fortify;

After this go to the file /app/Providers/RouteServiceProvider.php and write this function below the line public const HOME = ‘/dashboard’;

public const HOME = '/dashboard';

public static function redirectTo($guard){
return $guard.'/dashboard';
}

Then go to /app/Http/Middleware/RedirectIfAuthenticated.php and replace the line return redirect(RouteServiceProvider::HOME); with following line.

return redirect($guard.'/dashboard');

Now in the /app/Http/Middleware/ copy the file RedirectIfAuthenticated.php and paste it in the same folder and rename it to AdminRedirectIfAuthenticated.php then open it up and change the class name from RedirectIfAuthenticated to AdminRedirectIfAuthenticated.

So as we have created a new middleware so we need to register it now in app/Http/Kernel.php file so open it up and write following line in $middlewareAliases array.

'admin' => \App\Http\Middleware\AdminRedirectIfAuthenticated::class,

Now create a new folder in /app/Http/ named Responses and create a new file in this folder named LoginResponse.php

Then go to /vendor/laravel/fortify/src/Http/Responses/LoginResponse.php and copy its contents to this new file we just created and modify it as following

<?php

namespace App\Http\Responses;

use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract;
use Laravel\Fortify\Fortify;

class LoginResponse implements LoginResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? response()->json(['two_factor' => false])
: redirect()->intended('admin/dashboard');
}
}

Now run command

php artisan serve

And register a new user and try to login to which it may give error that credentials do not match.

Then try admin login. It gets logged in but redirects to same login page. So you can go to admin dashboard by http://localhost:8000/admin/dashboard and you will see the dashboard.

Now go to AdminController.php and modify following lines.

use App\Http\Responses\LoginResponse; // add new line
// use Laravel\Fortify\Contracts\LoginResponse; // remove or comment this one

Try to login again and it will work fine for admin.

Now we move on to user side. So open the files /app/Providers/FortifyServiceProvider.php and AdminController.php change the following lines in both files.

use App\Actions\Fortify\AttemptToAuthenticate; // add new line
use App\Actions\Fortify\RedirectIfTwoFactorAuthenticatable; // add new line
//use Laravel\Fortify\Actions\AttemptToAuthenticate; // remove or comment
//use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable; //remove or comment

Now go to following routes and check both admin and user logins.

http://localhost:8000/admin/login
http://localhost:8000/admin/admin/login

If you face any problem in the process steps then you can Download this project from here. And check out all the files and settings :)

Admin: admin@gmail.com
Password: password

User: user@gmail.com
Password: password

Congratulations! You’ve made it.

In the next part we will further work on User and Admin themes and dashboards sections.

--

--