我正在我的Laravel应用程序中试验中间件.目前,我已经将其设置为在每个路由上为经过身份验证的用户运行,但是,我希望它忽略任何以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);
    }
}

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

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.

有没有更好的方法可以让这个中间件为用户在所有路由上运行,但也可以设置某些应该免于此判断的路由?

推荐答案

你所做的没有错,但是,我建议你将路由分组,例如:

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

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

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

希望这能有所帮助!

Laravel相关问答推荐

我是否需要/是否可以从控制器运行LARLAVEL备份?

如何在laravel中输出奇偶行

Laravel created_at 返回对象代替数据库中的日期格式?

仅针对字母的 laravel 验证规则

Laravel belongsToMany 关系在两个表上定义本地键

Laravel 5在blade中 echo 包含html的会话变量

在 Laravel 5 中扩展请求类

Laravel 4 的 Cron 作业(job)

在 Laravel 中无效后防止重定向到主页

Twilio 查找 API 不起作用?

如何使用外部图像生成 html div 的 screenshot截图?

在 php Laravel 5 中创建自定义帮助函数的最佳实践是什么?

用于集合的 Laravel 5.5 API 资源

Laravel 字符串验证以允许空字符串

Guzzle 返回流空体而不是 json 体

Grammar::parameterize() 必须是数组类型

在 Laravel artisan 命令中使用详细

如何以及在哪里可以使用 laravel 存储图像?

带有 Xdebug 的 Laravel 5 总是抛出The payload is invalid..

Laravel 验证用户名不允许有空格