Home > other >  How can I use multiple middlewares on the same route name in Laravel 9?
How can I use multiple middlewares on the same route name in Laravel 9?

Time:06-27

I want my /dashboard page to be a different panel in 2 different user types. And return to home screen if not logged in. I created 2 middlewares to check if logged in user is "employer" or "employee". Whatever I do, I can't seem to make it work, it's been 2 days. I created middlewares and routes by following some very sketchy tutorials, it may hurt your eyes, be aware.

My route:

Route::get('/dashboard', function () {
    return view('welcome');
})->name('welcome');


Route::prefix('admin')->middleware([\App\Http\Middleware\isEmployer::class])->group( function () {
    Route::get("/dashboard", function (){
        return view("employer.dashboard");
    })->name("dashboard");
});


Route::prefix('store')->middleware([\App\Http\Middleware\isEmployee::class])->group( function(){
    Route::get("/dashboard", function (){
       return view("employee.dashboard");
    })->name("dashboard");
});

isEmployee middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class isEmployee
{
    public function handle(Request $request, Closure $next)
    {
        if(Auth::user())
        {
            if (Auth::user()->role == "employee")
            {
                return $next($request);
            }
        }

        return response()->view('welcome');
    }
}

isEmployer middleware :

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class isEmployer
{
    public function handle(Request $request, Closure $next)
    {
        if(Auth::user())
        {
            if (Auth::user()->role == "employer")
            {
                return $next($request);
            }
        }

        return response()->view('welcome');
    }
}

What I want to achieve is:

if not logged in : return welcome view

if logged in as employer : return employer.dashboard view

if logged in as employee : return employee.dashboard view

CodePudding user response:

Let's start from some refactoring:

  1. Make your routes/web.php a bit more readable:

    Route::view('/dashboard', 'welcome')->name('welcome');
    
    Route::prefix('admin')->name('admin.')->middleware('role:employer')->group(function() {
        Route::view('/dashboard', 'employer.dashboard')->name("dashboard");
    });
    
    Route::prefix('store')->name('store.')->middleware('role:employee')->group(function() {
        Route::view('/dashboard', 'employee.dashboard')->name("dashboard");
    });
    
  2. Now let's create a middleware that will check not only for one role, but for any role you give as a parameter:

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Auth;
    
    class HasRole
    {
        public function handle(Request $request, Closure $next, string $role)
        {
            if (Auth::user()?->role != $role) {
                return redirect()->route('welcome');
            }
    
            return $next($request);
        }
    }
    
  3. Now, create an alias in your app/Http/Kernel.php so you could use it like i wrote it in routes file role:<role_here>:

    protected $routeMiddleware = [
        // ...
        'role' => \App\Http\Middleware\HasRole::class,
    ];
    
    

Now for your question - how to use multiple middlewares for one route. It is simple:

$route->middleware(['middleware1', 'middleware2']);

You may attach them to groups or single routes:

Route::prefix('some_group')->middleware(['middleware1', 'middleware2'])->group(function() {
    Route::view("some.view")->middleware('middleware3')->name("some.view");
});

You can read more info about Laravel's middlewares here, and understand what responsibility chain is (pattern which middleware implements) under the hood. Also take a look at SOLID principles, mainly at DRY one. Have a good day =)

  • Related