Laravel 11 middleware provides a convenient mechanism for inspecting and filtering HTTP requests entering your application. Middleware is an essential component in Laravel applications. For example, whether you need to authenticate users, log requests, or enforce specific conditions, Laravel 11 Custom Middleware provides a flexible way to handle these tasks.

Laravel 11 Custom Middleware - How to make Multiple Authentications using auth in laravel 11 with Custom middleware?

Table Of Content

1 Prerequisites

1.) PHP version of 8.2
2.) Composer

2 Introduction

In this article, we'll explore the process of creating and registering Laravel 11 middleware along with practical examples to implement Laravel 11 multiple authentications using Laravel 11 Custom Middleware.

3 Create / Install a Laravel Project

3.1 Install Laravel Project For Laravel 11 Custom Middleware

First, make sure your computer has a composer.
Use the following command to install new Laravel Project.

composer create-project laravel/laravel laravel11-middleware-app

Then, navigate to your project directory:

cd laravel11-middleware-app

3.2 Configure MySql Database

Upon logging in, the user's record will be stored in the database. This process involves accessing the .env file to input and define the database credentials.

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

4 Install Auth using Scaffold

Laravel provided bootstrap scaffolding located in the laravel/ui Composer package, which may be installed using Composer.
Now we have to install laravel/ui package using the following command to create auth scaffold which are login, register and dashboard page
Install Laravel UI:
    
composer require laravel/ui
   
Once the laravel/ui package has been installed, you need to install the frontend scaffolding using the ui Artisan command. Run the bellow command.
    
  php artisan ui bootstrap --auth
   
Now Install npm dependencies by the bellow command.
    
  npm install
  

5 Update User Model and User Migration

Laravel 11 already includes a migration for the User model. In this Laravel 11 custom middleware example, you'll add a role field to the users table for differentiating between user types.

Update Migration File

Now we have to modify migration file Open the file /database/migrations/xxxx_xx_xx_create_users_table.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->tinyInteger('role')->default(0);
            $table->rememberToken();
            $table->timestamps();
        });

        Schema::create('password_reset_tokens', function (Blueprint $table) {
            $table->string('email')->primary();
            $table->string('token');
            $table->timestamp('created_at')->nullable();
        });

        Schema::create('sessions', function (Blueprint $table) {
            $table->string('id')->primary();
            $table->foreignId('user_id')->nullable()->index();
            $table->string('ip_address', 45)->nullable();
            $table->text('user_agent')->nullable();
            $table->longText('payload');
            $table->integer('last_activity')->index();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('users');
        Schema::dropIfExists('password_reset_tokens');
        Schema::dropIfExists('sessions');
    }
};
?>

Now we need to run command below to create table in database

php artisan migrate

Modify User Model File

Open the file /app/Models/User.php

<?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;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

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

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

    /**
     * Get the attributes that should be cast.
     *
     * @return array
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }
    /**
     * @param  integer  $value
     * @return \Illuminate\Database\Eloquent\Casts\Attribute
     */
    protected function role(): Attribute
    {
        return new Attribute(
            get: fn ($value) =>  ["user", "editor", "admin"][$value],
        );
    }
}
?>

6 Create Middleware and Implement Logic in Middleware

Create the Laravel 11 Custom Middleware to handle user roles. In the terminal, run:

php artisan make:middleware UserRoleMiddleware

The command will generate a file under directory /app/Http/Middleware/UserRoleMiddleware.php

Implement Logic in Middleware

We have to add new parameter '$role' to validate User role requested from web.php, we will implement if the role is match will allow to the next request, otherwise will redirect to home page open the file /app/Http/Middleware/UserRoleMiddleware.php

<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Auth;

class UserRoleMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next, $role): Response
    {
        if(Auth::check() && Auth::user()->role == $role)
        {
            return $next($request);
        }
        return redirect('home');
    }
}

?>

7 Register the Middleware

To use your Laravel 11 custom middleware, you need to register it in your application.
Laravel 11 introduces significant changes to middleware handling. In previous versions, you could register middleware in the Kernel.php file. However, with Laravel 11, you must define middleware in the bootstrap/app.php file.
Open the file bootstrap/app.php

<?php
namespace App\Http\Controllers\Auth;
uuse Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
        $middleware->alias([
            'role' => \App\Http\Middleware\UserRoleMiddleware::class,
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

?>

8 Modify Controller - HomeController and LoginController

In this step, we are going to use default home controller and add method userHome(), managerHome(), and adminHome() open the file /app/Http/Controllers/HomeController.php

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function userHome()
    {
        return view('home',["msg"=>"Hello! I am user"]);
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function managerHome()
    {
        return view('home',["msg"=>"Hello! I am Manager"]);
    }


    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function adminHome()
    {
        return view('home',["msg"=>"Hello! I am admin"]);
    }
}

?>

9 Define a Route

Define routes for Laravel 11 multiple authentications with the newly created middleware in web.php:
routes/web.php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController;
use App\Http\Middleware\UserRoleMiddleware;
Route::get('/', function () {
    return view('welcome');
});
Auth::routes();
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
// Route User
Route::middleware(['auth','App\Http\Middleware\UserRoleMiddleware:user'])->group(function()
{
    Route::get("/home",[HomeController::class, 'userHome'])->name("home");
});
// Route Manager
Route::middleware(['auth','App\Http\Middleware\UserRoleMiddleware:manager'])->group(function()
{
    Route::get("/manager/home",[HomeController::class, 'managerHome'])->name("manager.home");
});
// Route Admin
Route::middleware(['auth','App\Http\Middleware\UserRoleMiddleware:admin'])->group(function()
{
    Route::get("/admin/home",[HomeController::class, 'adminHome'])->name("admin.home");
});

10 Update Home Blade File

Modify home blade to display username and role
resources/views/home.blade.php


    @extends('layouts.app')

    @section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <h4>Get Sample Code</h4>
                <div class="card">
                    <div class="card-header">{{ __('Dashboard') }}</div>
    
                    <div class="card-body">
                        @if (session('status'))
                            <div class="alert alert-success" role="alert">
                                {{ session('status') }}
                            </div>
                        @endif
                        {{ Auth::user()->name }}
                        <br>
                        {{$msg}}
                    </div>
                </div>
            </div>
        </div>
    </div>
    @endsection


11 Add Seeder for Testing

Now create a seeder "CreateUserSeeder"
Use the following artisan command to Create Controller.

php artisan make:seeder CreateUserSeeder

database/seeders/CreateUserSeeder.php

<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\User;

class CreateUserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $users = [
            [
               'name'=>'User',
               'email'=>'user@getsamplecode.com',
               'role'=> 0,
               'password'=> bcrypt('123456'),
            ],
            [
               'name'=>'Manager',
               'email'=>'manager@getsamplecode.com',
               'role'=> 1,
               'password'=> bcrypt('123456'),
            ],
            [
               'name'=>'Admin',
               'email'=>'admin@getsamplecode.com',
               'role'=> 2,
               'password'=> bcrypt('123456'),
            ],
            
        ];
    
        foreach ($users as $key => $user) 
        {
            User::create($user);
        }
    }
}
?>

Use the following artisan command to run seeder.

php artisan db:seed --class=CreateUserSeeder

12 Folder Structure

13 Run Laravel Server to Test the App

Use the following artisan command to Test the App.

php artisan serve

14 Conclusion

This tutorial shows how to add custom middleware in Laravel 11 to create a robust and secure authentication system tailored to different user roles.

Tags