web-dev-qa-db-fra.com

Appliquer le middleware à toutes les routes sauf `setup / *` in Laravel 5.4

J'expérimente le middleware dans mon Laravel. Je l'ai actuellement configuré pour s'exécuter sur chaque route pour un utilisateur authentifié, cependant, je veux qu'il ignore toutes les demandes commençant par setup URI.

Voici à quoi ressemble ma méthode middleware CheckOnboarding:

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);
    }
}

Ceci est utilisé dans mes itinéraires comme ceci:

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');
    }); 
});

Maintenant, si je vais dans /home Ou /account Je suis redirigé vers /setup Comme vous vous y attendez. Cela a provoqué à l'origine une erreur de boucle de redirection, d'où la raison pour laquelle & $request->path() != 'setup' est dans le middleware.

J'ai l'impression que c'est une façon vraiment maladroite de le faire, et ne correspond évidemment à rien après setup comme la route setup/settings Que j'ai créée.

Existe-t-il un meilleur moyen d'exécuter ce middleware sur toutes les routes pour un utilisateur, mais également de définir certaines routes qui devraient être exemptées de cette vérification?

10
Andy Holmes

Il n'y a rien de mal à ce que vous faites, cependant, je suggérerais plutôt de diviser vos groupes d'itinéraire, c'est-à-dire:

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');
});

Vous pouvez également avoir un groupe parent pour votre authentification:

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');
    });
});

Cela signifie également que vous pouvez supprimer la condition supplémentaire de votre 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');

J'espère que cela t'aides!

15
Rwd

Vous pouvez utiliser la classe Controller pour cela avec des résultats assez spectaculaires.

Si vous créez une fonction __construct dans HTTP/Controllers/Controller.php, vous pouvez déclarer le middleware à exécuter sur chaque action du contrôleur et même déclarer des exceptions si nécessaire.

class Controller extends BaseController
{
  use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
  public function __construct(){
    $this->middleware('auth',['except' => ['login','setup','setupSomethingElse']]);
  }
}

Faites attention à ne mettre aucune des fonctions standard d'indexation, de stockage, de mise à jour, de destruction dans l'exception ou vous ouvrirez des problèmes de sécurité potentiels.

11
bstory

Routes sur lesquelles vous ne voulez pas que le middleware s'exécute, mettez-les simplement en dehors de la fonction:

//here register routes on which you dont want the middleware: checkOnboarding
Route::group(['middleware' => ['auth','checkOnboarding']], function () {
     //routes on which you want the middleware
});
2
Learner