Laravel 5:按用户组限制对控制器的访问

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31447217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:57:26  来源:igfitidea点击:

Laravel 5 : Restrict access to controllers by User group

phplaravelmodel-view-controllerlaravel-5.1

提问by Krenor

I've started learning Laravel 5.1 and so far I'm liking it! But there is one thing I don't get yet..
In my previous project I had 2 specific controllers (eg: "normal", "extended") which , after a successfull login, were called based on the Users user_groupfrom the database.

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

If "Foo.Bar" enters his valid credentials and has the group normalhe is redirected to NormalControler. Since I wasn't using any framework I restricted access to the other group by setting a $_SESSIONwith the group and checking it. So if another group tried to access that controller he got redirected.

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

How would this be achievable in Laravel 5? So far I have a controller which is callable without an Authentication and one restricted by this code in routes.php:

这在 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
});

And the login looks like this :

登录看起来像这样:

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

----- EDIT-----

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

I've run the artisan command and made this middleware as you suggested :

我已经运行了 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');
    }
}

and edited this line into Kernel.phpinto $routeMiddleware:

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

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

I think this is done right so far, correct me if I'm wrong! Could I then do something like this to restrict the controllers?

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

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

});

采纳答案by Almazik G

Ok, here is what you might do. Once user is logged in, you would check his credentials, get his user_groupand decide what controller he should be redirected to.

好的,这是你可以做的。用户登录后,您将检查他的凭据,获取他的凭据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');

This will handle right routing after logging in.

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

The next portion where you need to protect you routes from unwanted user groups may be achieved with middlewares.

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

  1. do an artisan command php artisan make:middleware ShouldBeInGroup
  2. go to app/http/Kernel.phpand add your new middleware to the routeMiddlewarearray. Key of the item might be anything you like. Let's call in inGroup. So: 'inGroup' => 'App\Http\Middleware\ShouldBeInGroup'
  3. Now, in your controller, in constructor, you are able to call this middleware
  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

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

  1. at lastly, work on the our middleware. Open newly created ShouldBeInGroupclass and edit the handle method.

    public function handle($request, Closure $next, $groupName)
    {
        if (Auth::check() && Auth::user()->inGroup($groupName)) {
             return $next($request);
        }
    
        return redirect('/');
    }
    
  2. And finally you should work on inGroupmethod, that should return trueof false. I assume that you have user_groupfield your users table. Then in your Usereloquent model add the method

    public function inGroup($groupName) {
        return $this->user_group == $groupName;
    }
    
  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雄辩模型中添加方法

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


Edit

编辑

if you want to use this middleware in your routes, you can do the following

如果你想在你的路由中使用这个中间件,你可以执行以下操作

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

But generally it's better to put all your middlewares into your Controller's constructor

但通常最好将所有中间件放入 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']];
}


And also on this note, Laravel provides built in authmiddleware that you can use

并且在此说明中,Laravel 提供auth了您可以使用的内置中间件

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

so then your routes would become much cleaner, just:

那么你的路线会变得更干净,只是:

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

回答by Needpoule

I think the best way to do that is using middlewares. See the doc here

我认为最好的方法是使用中间件。请参阅此处的文档

You can easily create a middleware using the following artisan command:

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

php artisan make:middleware ExtendedMiddleware

If you can't or don't want to use artisan, you need to create a class in The App/Http/Middlewarefolder.

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

In this class you'll need the following method to handle the request. In the method you can check for the user group.

在本课程中,您将需要以下方法来处理请求。在该方法中,您可以检查用户组。

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

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

You can then use this middleware in your route.phpfile:

然后你可以在你的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

});

回答by Chung

You can create a Middleware called : PermissionFilter

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

In PermissionFilter, you check if requesting user is in the group or not.

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

I can't provide a demo for now, but if you want I can make a demo later.

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

L5 middleware: http://laravel.com/docs/5.1/middleware

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