如何在 Laravel 4 中根据用户类型制作路由过滤器


How to make a route filters base on user type in Laravel 4?

目标:我想使用 Route::groupRoute::filter 在 Laravel 4 中制作路由过滤器


描述

我有2种类型的用户:

  1. 内部
  2. 分配器

对于,Internal,我有 2 组:

  • 管理
  • 定期

对于Distributor,我有4组:

  • 青铜
  • 整车厂

符合条件的路线

OEM 分销商仅有资格使用 5 条路线。

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

常规分销商有资格使用8条路线。

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

法典

  • 过滤器.php
  • 路线.php。

问题

  • 有人可以帮助我或至少引导我走向正确的方向吗?

首先:声明两次导致相同 URL 的路由是不可能的。(好吧,如果你有一个prefix的组,这是可能的,因为前缀会更改为路由的URL)

你必须通过智能过滤来解决这个问题

这是我想出的最简单的解决方案:

Route::filter('distributor', function(){
    $user = Auth::user();
    if($user->type == "Distributor"){
        return true;
    }
    if (Request::ajax()){
        return Response::make('Unauthorized', 404);
    }
    return View::make('errors.404_auth');
});
Route::filter('distributor.regular', function(){
    $user = Auth::user();
    if($user->type == "Distributor"){
        if($user->distributor()->type != 'OEM'){
            return true;
        }
    }
    if (Request::ajax()){
        return Response::make('Unauthorized', 404);
    }
    return View::make('errors.404_auth');
});

distributor筛选器仅检查用户是否为 Distributor 类型。第二个筛选器 distributor.regular 检查分销商是否不是 OEM。(如果你想知道,distributor.regular中的点没有特殊的功能或更深的含义。我就是喜欢这样写)

Route::group(['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::group(['before' => 'distributor.regular'], function(){
        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');
    });
});

这应该已经适用于您发布的用例。但是,我们可以使过滤器更加灵活,并减少冗余代码。

function makeError404(){
    if (Request::ajax()){
        return Response::make('Unauthorized', 404);
    }
    return View::make('errors.404_auth');
}
Route::filter('distributor', function(){
    $user = Auth::user();
    if($user->type == "Distributor"){
        return true;
    }
    return makeError404();
});
Route::filter('distributor.group', function($route, $request, $value){
    $groups = explode(';', $value);
    $user = Auth::user();
    if($user->type == "Distributor"){
        if(in_array($user->distributor()->type, $groups)){
            return true;
        }
    }
    return makeError404();
});

现在我们可以动态指定用户必须在哪个组中...

Route::group(['before' => 'distributor'], function(){
    // distributor routes
    Route::group(['before' => 'distributor.group:gold;silver;bronze'], function(){
        // regular routes
    });
});

你可以遵循这样的路径

class UserController extends BaseController {
    /**
     * Instantiate a new UserController instance.
     */
    public function __construct()
    {
        $this->beforeFilter('employee', array('only' => 'index'));
    }
}