Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

peterpan666's avatar

Call a middleware from another middleware

Hi all!

Is it possible to call a middleware each time another one is called? (I'm taking about route midleware).

I have a middleware 'foo' and a middleware 'bar'.

I want 'bar' to be called each time there is 'foo'.

This way I don't have to do inside my controller:

$this->middleware('foo');
$this->middleware('bar');
0 likes
9 replies
pmall's avatar

Just chain them Route::group(['middleware' => 'foo|bar'], function() {});

And, why do you want to have two middleware instead of only one ?

peterpan666's avatar

Yeah chaining isn't good because I still have to write both.

I have two middleware because sometimes I just need 'foo' but when I need 'bar' I ALWAYS need 'foo' ans I'm not fund of duplicate code so...

peterpan666's avatar
peterpan666
OP
Best Answer
Level 5

Ok found it finally!

Just for the records, what I wanted was to call (in this case) the Authenticate middleware every time I called another one middleware that checks some permissions and stuff on the auth user. Just to be DRY and to separate the logic, I wanted to still use the basic auth middleware without duplicating code or use something complex...

Here is what I've done:

namespace App\Http\Middleware;

class YourMiddleware
{
    public function handle($request, Closure $next)
    {
        //First you need to instantiate the middleware you want to use and call the handle method on it.
        //Then you have to create a closure where you'll do all your logic.
        return app(Authenticate::class)->handle($request, function ($request) use ($next) {
            //Put your awesome stuff there. Like:
            if ($someTestsFails) {
                return redirect()->home();
            }

            //Then process the next request if every tests passed.
            return $next($request);
        });
    }
}

Pretty simple stuff and it works great :)

5 likes
geozak's avatar

I know this is kinda old but I was looking for this exact situation and I think I found a (as jeffery says) more laravel like way to do it. To be fair I think this may have been implemented in a newer version of laravel than what was available when this was posted.

I looked into how the 'can' => \Illuminate\Auth\Middleware\Authorize::class, middleware worked and came up with this

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;

class YourMiddleware
{
    /**
     * The authentication factory instance.
     *
     * @var \Illuminate\Contracts\Auth\Factory
     */
    protected $auth;

    public function __construct(Auth $auth)
    {
        $this->auth = $auth;
    }

    public function handle($request, Closure $next)
    {
        $this->auth->authenticate();

        if($someTestFails) {
            return redirect()->home();
        }

        return $next($request);
    }
}

Although this does not work (as is) with the generalized question in the OP.

ashisharyal's avatar

what about this?

Route::group(['middleware' => ['foo', 'bar']], function () { Route::resource('unicorn', 'UnicornsController'); });

defayeke's avatar

@geozak why go to all that trouble if you can just call Auth::authenticate();? This isn't exactly an alternative to calling any middleware surely??

    /**
     * Determine if the current user is authenticated.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable
     *
     * @throws \Illuminate\Auth\AuthenticationException
     */
    public function authenticate()
    {
        if (! is_null($user = $this->user())) {
            return $user;
        }

        throw new AuthenticationException($this);
    }

@peterpan666 have you seen geozak's solution? What do you make of yours 2 years on? Would you do anything differently?

praveenp's avatar

I have included Google Two Factor authentication and it worked well. We have changed product design to giving option to users to enable two factor authentication.

I need to show otp screen on successful login.

In this case I want include 2fa middleware on successful login case only.

How do I solve this problem.

Thanks, Praveen

martinbean's avatar

@praveenp Create a new topic with your question instead of tagging it on the end of an already-existing topic.

Please or to participate in this conversation.