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

});
Author: Krenor, 2015-07-16

3 answers

Хорошо, вот что вы могли бы сделать. Как только пользователь войдет в систему, вы проверите его учетные данные, получите его 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');
 2
Author: Almazik G, 2015-07-16 12:03:48

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

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

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

});
 2
Author: Needpoule, 2015-07-16 08:14:25

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

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

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

Промежуточное программное обеспечение L5: http://laravel.com/docs/5.1/middleware

 0
Author: Chung, 2015-07-16 08:03:12