【问题标题】:Laravel 5 : Restrict access to controllers by User groupLaravel 5:按用户组限制对控制器的访问
【发布时间】:2015-07-16 06:53:11
【问题描述】:

我已经开始学习 Laravel 5.1,到目前为止我很喜欢它!但有一件事我还没有得到..
在我之前的项目中,我有 2 个特定的控制器(例如:“正常”、“扩展”),在成功登录后,它们根据数据库中的用户 user_group 被调用。

如果“Foo.Bar”输入他的有效凭据并拥有normal 组,他将被重定向到NormalControler。由于我没有使用任何框架,因此我通过在组中设置$_SESSION 并对其进行检查来限制对其他组的访问。因此,如果另一个组试图访问该控制器,他就会被重定向。

这在 Laravel 5 中如何实现?到目前为止,我有一个无需身份验证即可调用的控制器,并且在routes.php 中受此代码限制:

// All routes in the group are protected, only authed user are allowed to access them
Route::group(array('before' => 'auth'), function() {

    // TO-DO : Seperate Controller access
});

登录界面如下所示:

public function performLogin()
    {   

        $logindata = array(
            'username' => Input::get('user_name'),
            'password' => Input::get('user_pass')
        );

        if( Auth::attempt( $logindata ) ){
            // return \Redirect::to( check group and access this controller based on it);
        }
        else {
           // TO-DO : Redirect back and show error message
           dd('Login failed!');
        }
    }

----- 编辑 -----

我已经按照你的建议运行了 artisan 命令并制作了这个中间件:

namespace App\Http\Middleware;

use Closure;
use Request;

class GroupPermissions
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, $group)
    {
        // Check User Group Permissions
        if( $request->user()->group === $group ){
            // Continue the request
            return $next($request);
        }

        // Redirect
        return redirect('restricted');
    }
}

并将这一行编辑成Kernel.php$routeMiddleware

'group.perm' => \App\Http\Middleware\GroupPermissions::class

到目前为止,我认为这是正确的,如果我错了,请纠正我!然后我可以做这样的事情来限制控制器吗?

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

    Route::group( ['middleware' => 'group.perm', 'group' => 'normal'], function(){
        Route::get('/normal/index', 'DummyNormalController@index');
    });

    Route::group( ['middleware' => 'group.perm', 'group' => 'extended'], function(){
        Route::get('/extended/index', 'DummyExtendedController@index');
    });

});

【问题讨论】:

标签: php laravel model-view-controller laravel-5.1


【解决方案1】:

好的,这就是你可以做的。用户登录后,您将检查他的凭据,获取他的 user_group 并决定应将他重定向到哪个控制器。

if( Auth::attempt( $logindata ) ){
    $user = Auth::user();

    if ($user->inGroup('normal')) {
         return redirect()->route('normal_controllers_named_route');
    }
    return redirect()->route('extended_controllers_named_route');
}

return redirect()->back()->withFlashMessage('don\'t get me wrong');

这将在登录后处理正确的路由。

下一部分您需要保护您的路由免受不需要的用户组的影响,可以使用中间件来实现。

  1. 做一个工匠命令php artisan make:middleware ShouldBeInGroup
  2. 转到app/http/Kernel.php 并将您的新中间件添加到routeMiddleware 数组中。项目的关键可能是你喜欢的任何东西。让我们致电inGroup。所以:'inGroup' => 'App\Http\Middleware\ShouldBeInGroup'
  3. 现在,在您的控制器中,在构造函数中,您可以调用此中间件

$this->middleware('inGroup:extended'); //we also passing the name of the group

  1. 最后,处理我们的中间件。打开新创建的ShouldBeInGroup 类并编辑句柄方法。

    public function handle($request, Closure $next, $groupName)
    {
        if (Auth::check() && Auth::user()->inGroup($groupName)) {
             return $next($request);
        }
    
        return redirect('/');
    }
    
  2. 最后你应该使用inGroup 方法,它应该返回truefalse。我假设您有user_group 字段您的用户表。然后在你的User eloquent 模型中添加方法

    public function inGroup($groupName) {
        return $this->user_group == $groupName;
    }
    

编辑

如果您想在路由中使用此中间件,您可以执行以下操作

Route::group(array('before' => 'auth'), function() {
    Route::get('/normal/index', ['middleware' => 'group.perm:normal', 'uses' =>'DummyNormalController@index']);
}

但通常最好将所有中间件放入 Controller 的构造函数中

public function __construct(){
    $this->middleware('group.perm:normal'); // you can also pass in second argument to limit the methods this middleware is applied to : ['only' => ['store', 'update']];
}

另外,Laravel 提供了内置的 auth 中间件供您使用

public function __construct(){
    $this->middleware('auth');
    $this->middleware('group.perm:normal');
}

所以你的路线会变得更干净,只是:

Route::get('normal/index', 'DummyNormalController@index');

【讨论】:

  • 你能看看我的编辑吗?按照我的理解,这基本上是正确的吗?
  • @AndrewMalinnkov 谢谢,现在我更容易理解了! :)
【解决方案2】:

我认为最好的方法是使用中间件。 See the doc here

您可以使用以下工匠命令轻松创建中间件:

php artisan make:middleware ExtendedMiddleware

如果您不能或不想使用 artisan,则需要在 App/Http/Middleware 文件夹中创建一个类。

在这个类中,您将需要以下方法来处理请求。在方法中您可以检查用户组。

public function handle($request, Closure $next)
{
    // check user group
    if( user_group_ok )
        return $next($request); // Continue the request

    return redirect('restricted'); // Redidrect 
}

然后您可以在 route.php 文件中使用此中间件:

Route::group(['middleware' => 'auth'], function()
{

    // Logged-in user with the extended group
    Route::group(['middleware' => 'extended'], function()
    {
        // Restricted routes here
    });

    // Normal routes here

});

【讨论】:

    【解决方案3】:

    您可以创建一个名为:PermissionFilter 的中间件

    在 PermissionFilter 中,您检查请求用户是否在组中。

    我暂时无法提供演示,但如果您愿意,我可以稍后制作演示。

    L5 中间件:http://laravel.com/docs/5.1/middleware

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-02
      • 2019-11-05
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多