Home > Back-end >  Laravel route group and middlewares
Laravel route group and middlewares

Time:12-07

i am working on a laravel project with users who can have status verified (email verified).

on the other hand, users can have a subscription which is verified by a "subscriptions" middleware.

So I have several groups of routes including 2 of which the only difference is the presence of subscription or not

group 1:

Route::group(['middleware' => ["auth:sanctum", "verified"]], function () {}

group 2

Route::group(['middleware' => ["auth:sanctum", "verified", "subscriptions"]], function () {}

my question is about the order laravel uses for routes in these groups. for example if the user satisfies all the middleware of the first group, does laravel test the middleware of the second? Does a user verified have a chance to enter the second group of routes with subscription?

conversely, if the user does not have a subscription, he will not pass the subscription middleware. but I have the impression that the user is redirected by the subscription middleware which fails while laravel could find the right route in the group without this middleware (group 1)

what I would like is that it just tests for the presence of a subscription and that if it does not find one it looks for the route in group1.

Does the order of the groups in the code have an impact on the processing?

thanks.

edit:

Route::group(['middleware' => ["auth:sanctum", "verified", ]], function () {
            Route::get("/new", function () {
               // redirect to payment
            })->name("new-payment");
    }


Route::group(['middleware' => ["auth:sanctum", "verified", "subscriptions"]], function () {
    Route::get("/new", function () {
        return view("bourse-new");
    })->name("new-abo");

it is the same route but with a different behavior depending on the presence or not of a subscription When subscriptions middleware fails, it's redirect to "home", but i want laravel to use the first route

CodePudding user response:

my question is about the order laravel uses for routes in these groups. for example if the user satisfies all the middleware of the first group, does laravel test the middleware of the second?

If you hit a route included in the first group laravel won't check the other one.

Does a user verified have a chance to enter the second group of routes with subscription?

If he hasn't the subscription he cannot

Does the order of the groups in the code have an impact on the processing?

Yes, if you used the same uri the last one will override the previous one

Route::group(['middleware' => ["auth:sanctum", "verified", ]], function () {
            Route::get("/new", function () {
               // redirect to payment
            })->name("new-payment");
    }


Route::group(['middleware' => ["auth:sanctum", "verified", "subscriptions"]], function () {
    Route::get("/new", function () {
        return view("bourse-new");
    })->name("new-abo");

Try php artisan route:list, the second group is probably overriding the first

ok thanks, but I want a different behavior depending on the presence or not of a subscription

In User Model:

public function hasSubscribed()
{
    //do your logic to check if has subscription
}

You could use the first group and check if the Auth::user() has subscribed. something like this:

if (auth()->user()->hasSubscribed()) { 
    return view()
} 
    
//or ...

CodePudding user response:

In app/Http/Kernel.php

protected $middlewarePriority = [
    \Illuminate\Cookie\Middleware\EncryptCookies::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
    \Illuminate\Routing\Middleware\ThrottleRequests::class,
    \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];

Docs: https://laravel.com/docs/8.x/middleware#sorting-middleware

CodePudding user response:

thanks to @NoobDev.

I took over his solution by integrating the subscription tests into middleware

Route::group(['middleware' => ["auth:sanctum", "verified", function () {
    Route::get("/new", function () {
        return view("bourse-new");    
    })->middleware("subscriptions")->name("bourse-new");
}

and the subscriptions middleware:

public function handle(Request $request, Closure $next){
    if( //logic tests) {
         return $next($request);
     }
     return redirect('/checkout'); //redirect to payment
}

this solution is almost perfect, thanks everyone

  • Related