Laravel 5: ограничить доступ к контроллерам по группе пользователей

Я начал изучать 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');
    });

});

person Krenor    schedule 16.07.2015    source источник
comment
Промежуточное ПО должно это делать. думаю   -  person Nabin Kunwar    schedule 16.07.2015
comment
как говорили другие, промежуточное ПО теперь сделает это - mattstauffer.co/blog/ series / new-features-in-laravel-5.0   -  person marblewraith    schedule 16.07.2015


Ответы (3)


Хорошо, вот что вы можете сделать. Как только пользователь вошел в систему, вы должны проверить его учетные данные, получить его 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 методом, который должен возвращать true из false. Я предполагаю, что у вас есть user_group поле вашей таблицы пользователей. Затем в вашей User красноречивой модели добавьте метод

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

Но, как правило, лучше поместить все промежуточное ПО в конструктор вашего контроллера.

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');
person Almazik G    schedule 16.07.2015
comment
Не могли бы вы заглянуть в мою редакцию? Было ли это сделано правильно, как я понял? - person Krenor; 16.07.2015
comment
@AndrewMalinnkov Спасибо, теперь мне стало понятнее! :) - person Krenor; 16.07.2015

Я думаю, что лучший способ сделать это - использовать промежуточное программное обеспечение. См. документ здесь

Вы можете легко создать промежуточное ПО, используя следующую команду artisan:

php artisan make:middleware ExtendedMiddleware

Если вы не можете или не хотите использовать artisan, вам необходимо создать класс в папке The 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

});
person Needpoule    schedule 16.07.2015

Вы можете создать промежуточное ПО под названием: PermissionFilter

В PermissionFilter вы проверяете, находится ли запрашивающий пользователь в группе или нет.

Я не могу предоставить демоверсию сейчас, но если вы хотите, я могу сделать демо позже.

Промежуточное ПО L5: http://laravel.com/docs/5.1/middleware

person Chung    schedule 16.07.2015