如何正确过滤Laravel 4中的route :: group?
我遇到了route :: group filter的问题。
他们都是一样的。
底部路线组工作,顶部路线不。 :(
他们会重定向到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'));
});
已编辑添加Filters.php
目标:
用户类型=分销商
for user() - > type =" Distributor"
他们可以访问:
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');
答案 0 :(得分:1)
问题是:如果您没有为您的组定义前缀,Laravel在一个组中的路由与另一个组中的路由(共享相同的URL)之间没有区别
因为Laravel首先做的是搜索匹配的路线。之后完成所有过滤器内容(即使它在过滤器之前)。
在您的情况下,这意味着,例如Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController@show'));
组中的distributors
,会覆盖之前在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
等参数字符串
现在在函数中,字符串被分割(通过;
)保存在roles数组中
此数组用于检查是否允许某个角色并且当前用户是否拥有该角色。如果我们有匹配,它将返回到路线。如果没有条件为真,则返回错误。