Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply Middleware to all routes except `setup/*` in Laravel 5.4

I'm experimenting with Middleware in my Laravel application. I currently have it set up to run on every route for an authenticated user, however, I want it to ignore any requests that begin with the setup URI.

Here is what my CheckOnboarding middleware method looks like:

public function handle($request, Closure $next)
{
    /** 
    * Check to see if the user has completed the onboarding, if not redirect.
    * Also checks that the requested URI isn't the setup route to ensure there isn't a redirect loop.
    */
    if ($request->user()->onboarding_complete == false && $request->path() != 'setup') {
        return redirect('setup');
    } else {
        return $next($request);
    }
}

This is being used in my routes like this:

Route::group(['middleware' => ['auth','checkOnboarding']], function () {
    Route::get('/home', 'HomeController@index');
    Route::get('/account', 'AccountController@index');

    Route::group(['prefix' => 'setup'], function () {
        Route::get('/', 'OnboardingController@index')->name('setup');
        Route::post('/settings', 'SettingsController@store');
    }); 
});

Now, if I go to /home or /account I get redirected to /setup as you would expect. This originally caused a redirect loop error hence why & $request->path() != 'setup' is in the Middleware.

I feel like this is a really clunky way of doing it, and obviously doesn't match anything after setup like the setup/settings route I have created.

Is there a better way to have this Middleware run on all routes for a user, but also set certain routes that should be exempt from this check?

like image 652
Andy Holmes Avatar asked Mar 31 '17 07:03

Andy Holmes


People also ask

How do you use auth middleware in Laravel routes?

php file in your routes folder, then create your routes for Admin: <? php use Illuminate\Support\Facades\Route; // This route's name will be 'admin. dashboard' Route::get('dashboard', 'DashboardController@dashboard')->name('dashboard'); // This route's name will be 'admin.

How can you assign middleware in Laravel?

Assigning Middleware To Routes If you would like to assign middleware to specific routes, you should first assign the middleware a key in your application's app/Http/Kernel.php file. By default, the $routeMiddleware property of this class contains entries for the middleware included with Laravel.

Where do I register middleware in Laravel?

The middleware can be registered at app/Http/Kernel. This file contains two properties $middleware and $routeMiddleware.


1 Answers

There's nothing wrong with what you're doing, however, I would suggest splitting your route groups up instead i.e.:

Route::group(['middleware' => ['auth', 'checkOnboarding']], function () {
    Route::get('/home', 'HomeController@index');
    Route::get('/account', 'AccountController@index');
});

Route::group(['prefix' => 'setup', 'middleware' => 'auth'], function () {
    Route::get('/', 'OnboardingController@index')->name('setup');
    Route::post('/settings', 'SettingsController@store');
});

Alternatively, have a parent group for your auth:

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

    Route::group(['middleware' => 'checkOnboarding'], function () {
        Route::get('/home', 'HomeController@index');
        Route::get('/account', 'AccountController@index');
    });

    Route::group(['prefix' => 'setup'], function () {
        Route::get('/', 'OnboardingController@index')->name('setup');
        Route::post('/settings', 'SettingsController@store');
    });
});

This will also mean you can remove the extra condition in your middleware:

/**
 * Check to see if the user has completed the onboarding, if not redirect.
 * Also checks that the requested URI isn't the setup route to ensure there isn't a redirect loop.
 */
return $request->user()->onboarding_complete ? $next($request) : redirect('setup');

Hope this helps!

like image 160
Rwd Avatar answered Sep 28 '22 03:09

Rwd