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

secondman's avatar

Adding Middleware All But One Method in Controller

Here's my dilemma.

I'm creating a subscription app that needs to follow the flow below:

  1. Create account
  2. Confirm email --> redirect to select a plan
  3. Select plan and pay with Stripe/Cashier --> redirect to /account/profile/complete
  4. Fill in/validate required profile info
  5. Set user->status to active --> redirect to /account/dashboard

I have a middleware, UserHasActiveStatus that restricts users that aren't active:

public function handle($request, Closure $next) {
    $user = $request->user();

    if (auth()->user() && $user->status):
        return $next($request);
    endif;

    flash()->error('Please complete your profile before accessing this area.');
    
    return redirect('/account/profile/complete');
}

Now I need to find a way to add that to all account routes except account/profile/complete

My route group looks like this:

Route::group([
    'prefix'     => 'account', 
    'middleware' => ['auth', 'confirmed', 'subscribed']], function() {
        // additional routes here
        
        // Profile routes
        Route::get('/profile', 'Account\ProfileController@edit');
        Route::post('/profile', 'Account\ProfileController@update');

        // additional routes here
});

How can I apply this middleware so this it ignores account/profile/complete ?

Thanks

0 likes
8 replies
karlos545's avatar

add a second param to the middleware.

'middleware' => ['auth', 'confirmed', 'subscribed'],['except' => 'edit']]

@vkronlein Myself i prefer to pass middleware in the controller

    public function __contruct()
    {
        $this->middleware('manager',['except' => 'edit']);
    }
1 like
secondman's avatar

@karlos545

Route::group([
    'prefix'     => 'account', 
    'middleware' => ['auth', 'confirmed', 'subscribed', 'active']], function() {
        // additional routes here
        
        // Profile routes
        Route::get('/profile', 'Account\ProfileController@edit');
        Route::get('/profile/complete', 'Account\ProfileController@complete');
        Route::post('/profile', 'Account\ProfileController@update');

        // additional routes here
});

Handle method for the active middleware is shown in the question.

karlos545's avatar

sorry i thought it was the edit method the needed the middleware to ignore.

'middleware' => ['auth', 'confirmed', 'subscribed'],['except' => 'complete']]

Try that @vkronlein

thomaskim's avatar
Level 41

You could also use nested groups.

Route::group([
        'prefix' => 'account'
        'middleware' => 'auth'
    ], function() {

    // Routes that passed the auth middleware
    // You could put your account/profile/complete route here

    Route::group(['middleware' => ['confirmed', 'subscribed', 'active']], function() {
        // Routes that passed the confirmed, subscribed, and active middleware
    })
    
});
1 like
secondman's avatar

@thomaskim

All routes need to pass auth, confirmed, subscribed and active except profile/complete which must pass all except active.

Something like this maybe:

Route::group([
        'prefix' => 'account',
        'middleware' => ['auth', 'confirmed', 'subscribed']
    ], function() {

    // Routes that passed the auth, confirmed, subscribed middleware
    Route::get('/profile/complete', 'Account\ProfileController@complete');
    Route::post('/profile/complete', 'Account\ProfileController@store');

    Route::group(['middleware' => 'active'], function() {
        // Routes that passed auth, confirmed, subscribed, and active middleware

        // additional routes here

        Route::get('/profile', 'Account\ProfileController@edit');
        Route::post('/profile', 'Account\ProfileController@update');

        // additional routes here

    });
});

Please or to participate in this conversation.