将中间件应用于除 Laravel 5.4 中的“setup/*”之外的所有路由

我正在我的Laravel应用程序中试验中间件。我目前已将其设置为在经过身份验证的用户的每个路由上运行,但是,我希望它忽略以URI开头的任何请求。setup

以下是我的中间件方法: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);
    }
}

这在我的路由中使用,如下所示:

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

现在,如果我去或我被重定向到你期望的。这最初导致了重定向循环错误,因此为什么在中间件中。/home/account/setup& $request->path() != 'setup'

我觉得这是一种非常笨拙的方式,显然与我创建的路线不匹配。setupsetup/settings

有没有更好的方法让这个中间件在用户的所有路由上运行,同时也设置某些应该免除此检查的路由?


答案 1

你正在做的事情没有错,但是,我建议将你的路由组拆分为::

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

或者,为您的身份验证设置一个父组:

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

这也意味着您可以删除中间件中的额外条件:

/**
 * 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');

希望这有帮助!


答案 2

您可以利用 Controller 类来实现此目的,并获得非常壮观的结果。

如果在 HTTP/Controllers/Controller 中创建一个__construct函数.php则可以声明中间件在每个控制器操作上运行,甚至可以根据需要声明异常。

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

请注意不要将任何标准索引,存储,更新,销毁功能放在例外中,否则会打开潜在的安全问题。


推荐