Laravel 过滤路由

Posted

技术标签:

【中文标题】Laravel 过滤路由【英文标题】:Laravel Filter Routes 【发布时间】:2014-07-17 10:05:26 【问题描述】:

我正在使用 Laravel 4.1 构建一个应用程序。我的应用需要有两种不同的用户,管理员和客户。为此,我在用户表中添加了一个类型列,并在 /app/filters.php 中创建了自定义过滤器。

Route::filter('admin', function()

    if (Auth::guest() || Auth::user()->type !== 1) return Redirect::to('/');
);

Route::filter('client', function()

    if (Auth::guest() || Auth::user()->type != 2) return Redirect::to('/');
);

然后我在 /app/routes.php 中创建了 Route::group

/* Admin */
Route::group(array('before' => 'admin'), function()

    Route::get('admin', function() return "admin index"; );
    Route::get('ejemplo', function() return "admin ejmplo"; );
);

/* Client */
Route::group(array('before' => 'client'), function()

    Route::get('client', function() return "client index"; );
    Route::get('ejemplo', function() return "client ejmplo"; );
);

我面临的问题是我无法访问Route::get('ejemlo'),我想到了一个解决方案:

在路由组中添加 if 语句,因此只有 Auth::user()->type( [x] ) 可以访问某些路由。

但由于我对 laravel 很陌生,我不想弄乱我的代码,使其无法扩展或无法维护。

我对任何其他解决方案或结构设计持开放态度,

提前非常感谢您。 干杯

【问题讨论】:

这就是过滤器的用途...检查它们是否正常工作(例如,type 真的是 int 1 吗?) 是的,它是一个 int,当 Route::get('url') 重复时,过滤器工作得很好,我正在尝试命名路由,看看我是否可以让它工作 ejemplo作为client无法访问的问题吗? 我无法以管理员身份访问 ejemlo,但我可以以客户端身份访问 ejemlo 【参考方案1】:

不要重新定义同名的路由。路由旨在指向一个位置,过滤器旨在过滤对路由的访问,拒绝不符合条件的客户端(未经过身份验证、错误的 csrf 令牌、权限不足等)。

我会问自己,根据我目前的经验,你是否真的需要你的示例路线根据用户输入指向两个不同的地方,答案可能是否定的。

你有没有考虑过类似的事情

Route::group( array( 'prefix' => 'admin', 'before' => 'admin' ) function() 
    Route::get( 'admin',   function()  return "admin index";     );
    Route::get( 'example', function()  return "admin example";   );
);

Route::group( array( 'prefix' => 'client', 'before' => 'client' ), function() 
    Route::get( 'client',  function()  return "client index";    );
    Route::get( 'example', function()  return "client example";  );
);

然后你会通过

导航到那个
example.co.uk/admin/example
example.co.uk/client/example

如果这对您不起作用,并且您确实需要指向不同地方的路线,我会考虑的两个选项是

    使用您在第一篇文章中建议的 if 语句 在控制器中处理它

控制器示例:

function MyControllerFunction() 
    $user = Auth::user();
    if ( is_null( $user ) ) 
        HandleUserNotAuthed();
    
    if( Auth::user()->isAdmin ) 
        HandleAdminCodeHere();
     else 
        HandleClientCodeHere();
    

路线示例:

$user = Auth::user();
if( ! ( is_null( $user ) ) ) 
    if( $user->isAdmin ) 
        Route::get( 'admin',   function()  return "admin index";     );
        Route::get( 'example', function()  return "admin example";   );
     else 
        Route::get( 'client',  function()  return "client index";    );
        Route::get( 'example', function()  return "client example";  );
    

如您所知,最后两个示例非常混乱,除非您绝对必须拥有相同的 URL,否则我不会推荐它。查看您的应用程序并确定您是否可以使用不同的路由,如果可以,请这样做(:

【讨论】:

你是对的,我会使用前缀,从长远来看,这似乎是一个更好的解决方案!干杯!【参考方案2】:

Laravel 保存的路径是以 url 作为唯一索引的。这意味着除非您使用 if/else,否则您不能有两条具有相同 url 的路由。

我建议您创建另一个过滤器来检查用户是管理员还是客户端,然后将共享的Route 添加到新组。

过滤器

Route::filter('admin', function()

    if (Auth::guest() || Auth::user()->type !== 1) return Redirect::to('/');
);

Route::filter('client', function()

    if (Auth::guest() || Auth::user()->type != 2) return Redirect::to('/');
);

Route::filter('admin_or_client', function()

    if (Auth::guest() || ! in_array(Auth::user()->type, [1, 2])) return Redirect::to('/');
);

路线

/* Admin */
Route::group(array('before' => 'admin'), function()

    Route::get('admin', function() return "admin index"; );
);

/* Client */
Route::group(array('before' => 'client'), function()

    Route::get('client', function() return "client index"; )
);

/* Admin or Client */
Route::group(array('before' => 'admin_or_client'), function()

    Route::get('ejemplo', function() return "admin or client ejmplo"; );
);

【讨论】:

以上是关于Laravel 过滤路由的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4 过滤不同角色的组路由

Laravel 4 条件路由过滤器

laravel 路由过滤器检查用户角色

Laravel 将参数从路由传递到过滤器

Laravel,路由通配符过滤然后控制器

Laravel 5 路由过滤器正则表达式