Multi-User Authentication with Laravel Breeze and Inertia
Tags: laravel, breeze, inertia, react
Published: 2021-10-28 14:11:00

## Table of content <a name="toc"/>
* 1. [Introduction](#introduction)
* 2. [Packages required](#packages-required)
* 3. [Project setup](#setup)
* 3.1. [Laravel installation](#laravel-install)
* 3.2. [Laravel breeze installation](#laravel-breeze-install)
* 4. [Creating multiple user views or dashboard](#multi-user-views)
* 5. [Creating multiple user roles in the database](#multi-user-roles-db)
* 5.1. [Editing the users migration table](#migration-users-table)
* 5.2. [Editing the registration page](#registration-page)
* 5.3. [Editing the registration controller](#registration-controller)
* 5.4. [Editing the user model](#user-model)
* 6. [Multi-user authentication (main section)](#multi-user-authentication)
* 6.1. [Creating a middleware](#61-creating-a-middleware)
* 6.2. [Registering the middleware at the kernel](#62-registering-the-middleware-at-the-kernel)
* 6.3. [Redirecting users if authenticated](#63-redirecting-users-if-authenticated)
* 6.4. [Configuring routes](#64-configuring-routes)
* 7. [Conclusion](#70-conclusion)
* 8. [Acknowledgements](#80-acknowledgements)

## 1. Introduction <a name="introduction"/>
In this example, you will learn how to implement multi-authentication in laravel 8 and laravel breeze (inertia).

## 2. Package version <a name="packages"/>
* Laravel v8.x
* Laravel breeze v1.4

## 3. Project setup <a name="setup"/>        

### 3.1. Laravel Installation <a name="laravel-install"/>
We would be using composer to install our new laravel package [Laravel installation via composer](https://laravel.com/docs/8.x#installation-via-composer). 
If composer is not installed, install composer [here](https://getcomposer.org/download/).

```
composer create-project laravel/laravel example-app

cd example-app
```
### 3.2. Laravel Breeze installation <a name="#laravel-breeze-install"/>
Now in the project's root directory we would install breeze [Laravel Breeze](https://laravel.com/docs/8.x/starter-kits#laravel-breeze)

```
composer require laravel/breeze --dev

```
For this project I would be using [React](https://reactjs.org), but you can use [Vue](https://vuejs.org) if you want to.

```
php artisan breeze:install vue

// Or...

php artisan breeze:install react

npm install
npm run dev
```
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=
```
then run 
```
php artisan migrate
```
## 4. Creating Multiple User Views or Dashboard <a name="multi-user-views"/>
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**
```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>
  );
}

```

**GuestDashboard.js**
```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>
  );
}

```

**UserDashboard**

```js
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>
  );
}

```

**Dashboard (The default dashboard created by breeze)**
```js
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>
  );
}

```


## 5. Creating multiple user roles in the database <a name="multi-user-roles-db"/>

### 5.1. Editing the users migration table <a name="migration-users-table"/>

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

```php
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();
        });
    }
```
then run `php artisan migrate:refresh`.

### 5.2. Editing the registration page <a name="registration-page"/>

```js
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>

    .... 
  );
}

```

### 5.3. Editing the registration controller <a name="registration-controller"/>

```php
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
        ]);
    }
```
### 5.4. Editing the user model <a name="user-model"/>

```php
app/Models/User.php


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

```

## 6. Multi-User Authentication (main-section) <a name="multi-user-authentication"/>

### 6.1. Creating a middleware

Run the command `php artisan make:middleware CheckRole`

```php
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);
    }
```

### 6.2. Registering the middleware at the kernel

```php
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
    ];
```

### 6.3. Redirecting users if authenticated

#### Create a controller
Run `php artisan make:controller Auth/RedirectAuthenticatedUsersController`

```php
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();
        }
    }
}
```

####  Edit the Route service provider
```php
app/Providers/RouteServiceProvider.php


public const HOME = "/redirectAuthenticatedUsers"; //edit here
```

### 6.4. Configuring routes

```php
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');
    });
});
```
Make sure you import
```php
use App\Http\Controllers\Auth\RedirectAuthenticatedUsersController;
```

We are directly [rendering](https://inertiajs.com/routing) the components in the file, but you can create a [controller](https://laravel.com/docs/8.x/controllers#introduction) and render the components there, [check example](https://inertiajs.com/responses).

## 7. Conclusion
check the code from [Github](https://github.com/kachidk/multi-auth-laravel-breeze-inertia-demo)

## 8. Acknowledgements
- [Laravel article](https://laravelarticle.com/laravel-breeze)
- [Laravel](https://laravel.com/)
- [Inertia](https://inertiajs.com/)

[Table of Contents](#toc)