【问题标题】:How to properly filter your route::group in Laravel 4?如何在 Laravel 4 中正确过滤你的 route::group?
【发布时间】:2015-01-20 02:23:07
【问题描述】:

如何在 Laravel 4 中正确过滤你的 route::group ?

我的 route::group 过滤器有问题。

他们都是一样的东西。

底部的路由组有效,而顶部的路由组无效。 :(

他们一直重定向到 404,我不打算这样做。

谁能告诉我我做错了什么?

    ////////////////
    // OEM Routes //
    ////////////////

    Route::group(array('before'=>'oem'),function() {


        Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show'));
        Route::get('distributors/{id}/edit', 'DistributorController@edit');
        Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController@update'));

        Route::get('catalog_downloads','CatalogDownloadController@index');
        Route::get('catalog_downloads/{id}/download','CatalogDownloadController@file_download');


        });


    ////////////////////////
    //Distributor Routes  //
    ////////////////////////

     Route::group(array('before'=>'distributor'),function() {


        Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show'));
        Route::get('distributors/{id}/edit', 'DistributorController@edit');
        Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController@update'));

        Route::get('catalog_downloads','CatalogDownloadController@index');
        Route::get('catalog_downloads/{id}/download','CatalogDownloadController@file_download');

        Route::get('marketing_materials','MarketingMaterialController@index');
        Route::get('marketing_materials/{id}/download/thumb_path','MarketingMaterialController@thumb_download');
        Route::get('marketing_materials/{id}/download/media_path','MarketingMaterialController@media_download');

        Route::get('marketing_materials/{id}', array('before' =>'profile', 'uses'=>'MarketingMaterialController@show'));

        });

编辑添加过滤器.php

目标:

用户类型 = 分销商

for user()->type = "分销商"

他们可以访问这个:

 Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show'));
            Route::get('distributors/{id}/edit', 'DistributorController@edit');
            Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController@update'));

            Route::get('catalog_downloads','CatalogDownloadController@index');
            Route::get('catalog_downloads/{id}/download','CatalogDownloadController@file_download');

            Route::get('marketing_materials','MarketingMaterialController@index');
            Route::get('marketing_materials/{id}/download/thumb_path','MarketingMaterialController@thumb_download');
            Route::get('marketing_materials/{id}/download/media_path','MarketingMaterialController@media_download');

用户类型 = 经销商 + 经销商类型 = OEM

否则,如果 user()->type = "Distributor" AND Auth::user()->distributor()->first()->type == 'OEM'

他们只能访问:

                Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show'));
                Route::get('distributors/{id}/edit', 'DistributorController@edit');
                Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController@update'));

                Route::get('catalog_downloads','CatalogDownloadController@index');
                Route::get('catalog_downloads/{id}/download','CatalogDownloadController@file_download');

不是这个。。

            Route::get('marketing_materials','MarketingMaterialController@index');
            Route::get('marketing_materials/{id}/download/thumb_path','MarketingMaterialController@thumb_download');
            Route::get('marketing_materials/{id}/download/media_path','MarketingMaterialController@media_download');

【问题讨论】:

  • 你能告诉我们distributoroem这两个过滤器吗?
  • @lukasgeiter :我注意到,你总是帮助我。谢谢你的考虑。 :)
  • 关于过滤器,从一开始我就想在帖子中展示它,但是由于代码很多,所以不会让我这样做。我如何在评论中发布它而不会让你感到困惑。
  • 不客气,我是来帮忙的 ;) 你说的 SO won't let you 是什么意思?
  • 您知道,当我们发布大量代码而不是解释时,堆栈溢出 (SO) 会阻止您这样做。我不知道 - 也许我的名声很低。

标签: laravel laravel-4 routes laravel-routing


【解决方案1】:

问题是这样的:如果你没有为你的组定义前缀,Laravel 不会区分一个组中的路由和另一个组中的路由(共享相同的 url)

因为 Laravel 首先要做的是搜索匹配的路由。所有过滤器的东西都是在之后完成的(即使是之前的过滤器)。

在您的情况下,这意味着,例如 distributors 组中的 Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show')); 会覆盖之前在 oem 组中注册的相同路由

现在我们如何解决这个问题(同时让你的代码更多 DRY

首先,我们将编写一个新的过滤器来替换您已有的两个。我们就叫它role

Route::filter('role', function($route, $request, $value){
    if(Auth::user()->type == 'Distributor'){
        $authorized = true;

        if($value == 'distributor'){
            if(Auth::user()->distributor()->first()->type !==  'OEM'){
                $authorized = false;
            }
        }
        else if($value == 'oem'){
            if(Auth::user()->distributor()->first()->type ==  'OEM'){
                $authorized = false;
            }
        }
        else if($value == 'distributor+oem'){
            $authorized = false;
        }


        if(!$authorized){
            if(Request::ajax()){
                return Response::make('Unauthorized', 404);
            }
            else {
                return View::make('errors.404_auth');
            }
        }
    }
});

我不知道我在过滤器中的业务逻辑是否 100% 正确,但希望你了解基本原理。

这就是你使用它的方式:

Route::group(array('before'=>'role:distributor+oem'), function(){

    Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show'));
    Route::get('distributors/{id}/edit', 'DistributorController@edit');
    Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController@update'));

    Route::get('catalog_downloads','CatalogDownloadController@index');
    Route::get('catalog_downloads/{id}/download','CatalogDownloadController@file_download');

});


Route::group(array('before'=>'role:distributor'), function(){

    Route::get('marketing_materials','MarketingMaterialController@index');
    Route::get('marketing_materials/{id}/download/thumb_path','MarketingMaterialController@thumb_download');
    Route::get('marketing_materials/{id}/download/media_path','MarketingMaterialController@media_download');

    Route::get('marketing_materials/{id}', array('before' =>'profile', 'uses'=>'MarketingMaterialController@show'));
});

更新

你更新问题的目标,稍微改变一下......

Route::filter('role', function($route, $request, $value){
    $roles = explode(';', $value);
    $authorized = false;
    $user = Auth::user();
    if(in_array('distributor', $roles)){
        if($user->type == 'Distributor' && $user->distributor()->first()->type != 'OEM'){
            return;
        }
    }
    if(in_array('oem', $roles)){
        if($user->type == 'Distributor' && $user->distributor()->first()->type == 'OEM'){
            return;
        }
    }


    if(Request::ajax()){
        return Response::make('Unauthorized', 404);
    }
    else {
        return View::make('errors.404_auth');
    }
});

还有路线:

Route::group(array('before'=>'role:distributor;oem'), function(){

    Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show'));
    Route::get('distributors/{id}/edit', 'DistributorController@edit');
    Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController@update'));

    Route::get('catalog_downloads','CatalogDownloadController@index');
    Route::get('catalog_downloads/{id}/download','CatalogDownloadController@file_download');

});


Route::group(array('before'=>'role:distributor'), function(){

    Route::get('marketing_materials','MarketingMaterialController@index');
    Route::get('marketing_materials/{id}/download/thumb_path','MarketingMaterialController@thumb_download');
    Route::get('marketing_materials/{id}/download/media_path','MarketingMaterialController@media_download');

    Route::get('marketing_materials/{id}', array('before' =>'profile', 'uses'=>'MarketingMaterialController@show'));
});

说明

首先,您会找到有关路由过滤器here 的所有信息。但是,这是一个非常简短的版本:Route::filter('name', function(){}) 注册的过滤器函数被 Laravel 以路由对象、请求对象和过滤器参数 (filter:parameter) 依次作为参数调用。

这个过滤器功能具体是如何工作的?
为了能够传递多个“角色”,它使用role1;role2 等参数字符串
现在在函数中,字符串被拆分(通过;)保存在角色数组中。
该数组用于检查某个角色是否被允许并且当前用户是否拥有该角色。如果我们有匹配,它会返回到路由。如果没有一个条件为真,则返回错误。

【讨论】:

  • 我已经试过你的代码,它似乎没有工作。我很确定你很接近。我刚刚在帖子上编辑了我的确切目标。你介意帮我稍微调整一下你的代码 - 以适应我的情况。我是新手。我希望你不要介意。感谢您的帮助。
  • @evoque2015 不,我不介意;)我更新了答案。希望这有效
  • 你太棒了。我不知道除此之外该说什么。 :)
  • 你能解释一下这个函数($route, $request, $value) 吗?你怎么知道我们需要 3 个参数?这些变量的值是多少?你从哪里弄来的?
  • 当我以 user.type = Distributor 身份登录时,您的答案是完美的。但是,当我以 user.type = AdminOR user.type = something else 登录时,它会破坏我的一些链接。因此,我试图理解您在 ** filter.php ** 中的代码,所以也许我可以自己修改它。
猜你喜欢
  • 2014-03-02
  • 1970-01-01
  • 2015-03-08
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 2015-09-01
  • 1970-01-01
相关资源
最近更新 更多