DEV Community

Cover image for Multi-User Authentication with Laravel Breeze and Inertia
Victor Nwanguma
Victor Nwanguma

Posted on • Updated on

Multi-User Authentication with Laravel Breeze and Inertia

Table of content

1.0 Introduction πŸ“–

For clarity, clicking on πŸ“– would take you to the Table of content.

In this example, you will learn how to implementΒ multi-authentication in laravel 8 and laravel breeze (inertia).

2.0 Package version πŸ“–

  • Laravel v8.x
  • Laravel breeze v1.4

3.0 Project setup πŸ“–

3.1 Laravel Installation

We would be using composer to install our new laravel package Laravel installation via composer.
If composer is not installed, install composer here.

composer create-project laravel/laravel example-app

cd example-app
Enter fullscreen mode Exit fullscreen mode

3.2 Laravel Breeze installation

Now in the project's root directory we would install breeze Laravel Breeze

composer require laravel/breeze --dev

Enter fullscreen mode Exit fullscreen mode

For this project I would be using React, but you can use Vue if you want to.

php artisan breeze:install vue

// Or...

php artisan breeze:install react

npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Don't forget to create a database and include the details of the database in the .env file at the root directory

// fill all details
DB_CONNECTION=mysql 
DB_HOST=127.0.0.1
DB_PORT=""
DB_DATABASE=laravel
DB_USERNAME=""
DB_PASSWORD=
Enter fullscreen mode Exit fullscreen mode

then run

php artisan migrate
Enter fullscreen mode Exit fullscreen mode

4.0 Creating Multiple User Views or Dashboard πŸ“–

In this section we would be creating different views to route our different authenticated users to.

  • AdminDashboard.js
  • GuestDashboard.js
  • UserDashboard.js
  • Dashboard.js (The default dashboard created by breeze)

AdminDashboard.js

resources/js/Pages/AdminDashboard.js


import React from "react";
import Authenticated from "@/Layouts/Authenticated";
import { Head } from "@inertiajs/inertia-react";

export default function AdminDashboard(props) {
  return (
    <Authenticated
      auth={props.auth}
      errors={props.errors}
      header={
        <h2 className="text-xl font-semibold leading-tight text-gray-800">
          Admin Dashboard
        </h2>
      }
    >
      <Head title="Admin Dashboard" />

      <div className="py-12">
        <div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
          <div className="overflow-hidden bg-white shadow-sm sm:rounded-lg">
            <div className="p-6 bg-white border-b border-gray-200">
              You're logged in as Admin!
            </div>
          </div>
        </div>
      </div>
    </Authenticated>
  );
}

Enter fullscreen mode Exit fullscreen mode

GuestDashboard.js

resources/js/Pages/GuestDashboard.js


import React from "react";
import Authenticated from "@/Layouts/Authenticated";
import { Head } from "@inertiajs/inertia-react";

export default function GuestDashboard(props) {
  return (
    <Authenticated
      auth={props.auth}
      errors={props.errors}
      header={
        <h2 className="text-xl font-semibold leading-tight text-gray-800">
          Guest Dashboard
        </h2>
      }
    >
      <Head title="Dashboard" />

      <div className="py-12">
        <div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
          <div className="overflow-hidden bg-white shadow-sm sm:rounded-lg">
            <div className="p-6 bg-white border-b border-gray-200">
              You're logged in as Guest!
            </div>
          </div>
        </div>
      </div>
    </Authenticated>
  );
}

Enter fullscreen mode Exit fullscreen mode

UserDashboard

resources/js/Pages/UserDashboard.js


import React from "react";
import Authenticated from "@/Layouts/Authenticated";
import { Head } from "@inertiajs/inertia-react";

export default function Dashboard(props) {
  return (
    <Authenticated
      auth={props.auth}
      errors={props.errors}
      header={
        <h2 className="text-xl font-semibold leading-tight text-gray-800">
          User Dashboard
        </h2>
      }
    >
      <Head title="Dashboard" />

      <div className="py-12">
        <div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
          <div className="overflow-hidden bg-white shadow-sm sm:rounded-lg">
            <div className="p-6 bg-white border-b border-gray-200">
              You're logged in as User!
            </div>
          </div>
        </div>
      </div>
    </Authenticated>
  );
}

Enter fullscreen mode Exit fullscreen mode

Dashboard (The default dashboard created by breeze)

resources/js/Pages/Dashboard.js


import React from "react";
import Authenticated from "@/Layouts/Authenticated";
import { Head } from "@inertiajs/inertia-react";

export default function Dashboard(props) {
  return (
    <Authenticated
      auth={props.auth}
      errors={props.errors}
      header={
        <h2 className="text-xl font-semibold leading-tight text-gray-800">
          Default dashboard from Dashboard Breeze //edit here
        </h2>
      }
    >
      <Head title="Dashboard" />

      <div className="py-12">
        <div className="mx-auto max-w-7xl sm:px-6 lg:px-8">
          <div className="overflow-hidden bg-white shadow-sm sm:rounded-lg">
            <div className="p-6 bg-white border-b border-gray-200">
              You're logged in as User (Default dashboard from breeze)! //edit here
            </div>
          </div>
        </div>
      </div>
    </Authenticated>
  );
}

Enter fullscreen mode Exit fullscreen mode

5.0 Creating multiple user roles in the database πŸ“–

5.1 Editing the users migration table

we are going to create a role column in the users table.

database/migrations/create_users_table.php


public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('role'); //here
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }
Enter fullscreen mode Exit fullscreen mode

then run php artisan migrate:refresh.

5.2 Editing the registration page

resources/js/Pages/Auth/Register.js


export default function Register() {
  const { data, setData, post, processing, errors, reset } = useForm({
    name: "",
    email: "",
    role: "", // make sure this is present
    password: "",
    password_confirmation: "",
  });

  ....

  return (

        ....

        // put this after the email
        <div className="mt-4">
          <Label forInput="role" value="Role" />

          <select
            name="role" /* make sure this and data.role is the same */
            id="role"
            className="block w-full mt-1 rounded-md"
            onChange={onHandleChange}
          >
            <option value="user">User</option>
            <option value="admin">Admin</option>
            <option value="guest">Guest</option>
          </select>
        </div>

    .... 
  );
}

Enter fullscreen mode Exit fullscreen mode

5.3 Editing the registration controller

app/Http/Controllers/Auth/RegisteredUserController.php


public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'role' => 'required|string', //edit here
            'password' => ['required', 'confirmed', Rules\Password::defaults()],
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'role' => $request->role //edit here
        ]);
    }
Enter fullscreen mode Exit fullscreen mode

5.4 Editing the user model

app/Models/User.php


 protected $fillable = [
        'name',
        'email',
        'password',
        'role' //edit here
    ];

Enter fullscreen mode Exit fullscreen mode

6.0 Multi-User Authentication (main-section) πŸ“–

6.1 Creating a middleware

Run the command php artisan make:middleware CheckRole

app/Http/Middleware/CheckRole.php


public function handle(Request $request, Closure $next, string $role)
    {
        if ($role == 'admin' && auth()->user()->role != 'admin' ) {
            abort(403);
        }
        if ($role == 'user' && auth()->user()->role != 'user' ) {
            abort(403);
        }
        if ($role == 'guest' && auth()->user()->role != 'guest' ) {
            abort(403);
        }
        return $next($request);
    }
Enter fullscreen mode Exit fullscreen mode

6.2 Registering the middleware at the kernel

app/Http/Kernel.php


protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'checkRole' => \App\Http\Middleware\CheckRole::class, //edit here
    ];
Enter fullscreen mode Exit fullscreen mode

6.3 Redirecting users if authenticated

Create a controller

Run php artisan make:controller Auth/RedirectAuthenticatedUsersController

app/Http/Controllers/Auth/RedirectAuthenticatedUsersController.php


class RedirectAuthenticatedUsersController extends Controller
{
    public function home()
    {
        if (auth()->user()->role == 'admin') {
            return redirect('/adminDashboard');
        }
        elseif(auth()->user()->role == 'user'){
            return redirect('/userDashboard');
        }
        elseif(auth()->user()->role == 'guest'){
            return redirect('/guestDashboard');
        }
        else{
            return auth()->logout();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Edit the Route service provider

app/Providers/RouteServiceProvider.php


public const HOME = "/redirectAuthenticatedUsers"; //edit here
Enter fullscreen mode Exit fullscreen mode

6.4 Configuring routes

routes/web.php


/* Delete this
Route::get('/dashboard', function () {
    return Inertia::render('Dashboard');
})->middleware(['auth', 'verified'])->name('dashboard'); 
*/

Route::group(['middleware' => 'auth'], function() {
    Route::inertia('/dashboard', 'Dashboard')->name('dashboard');

    Route::get("/redirectAuthenticatedUsers", [RedirectAuthenticatedUsersController::class, "home"]);

    Route::group(['middleware' => 'checkRole:admin'], function() {
        Route::inertia('/adminDashboard', 'AdminDashboard')->name('adminDashboard');
    });
    Route::group(['middleware' => 'checkRole:user'], function() {
        Route::inertia('/userDashboard', 'UserDashboard')->name('userDashboard');
    });
    Route::group(['middleware' => 'checkRole:guest'], function() {
        Route::inertia('/guestDashboard', 'GuestDashboard')->name('guestDashboard');
    });
});
Enter fullscreen mode Exit fullscreen mode

Make sure you import

use App\Http\Controllers\Auth\RedirectAuthenticatedUsersController;
Enter fullscreen mode Exit fullscreen mode

We are directly rendering the components in the file, but you can create a controller and render the components there, check example.

7.0 Conclusion πŸ“–

check the code from Github

8.0 Acknowledgements πŸ“–

Discussion (0)