【问题标题】:Laravel Filter RoutesLaravel 过滤路由
【发布时间】: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

标签: php laravel


【解决方案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

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

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

控制器示例:

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

【讨论】:

    猜你喜欢
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 2012-11-19
    相关资源
    最近更新 更多