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');
});
});
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');
Это будет обрабатывать правильную маршрутизацию после входа в систему.
Следующая часть, в которой вам необходимо защитить свои маршруты от нежелательных групп пользователей, может быть достигнута с помощью промежуточных программ.
- выполните команду ремесленника
php artisan make:middleware ShouldBeInGroup
- перейдите к
app/http/Kernel.php
и добавьте новое промежуточное программное обеспечение в массивrouteMiddleware
. Ключ от предмет может быть любым, что вам нравится. Давайте позовемinGroup
. Итак:'inGroup' => 'App\Http\Middleware\ShouldBeInGroup'
- Теперь в вашем контроллере, в конструкторе, вы можете вызвать это промежуточное программное обеспечение
$this->middleware('inGroup:extended'); //we also passing the name of the group
-
Наконец, поработайте над нашим промежуточным программным обеспечением. Откройте только что созданный класс
ShouldBeInGroup
и отредактируйте метод дескриптора.public function handle($request, Closure $next, $groupName) { if (Auth::check() && Auth::user()->inGroup($groupName)) { return $next($request); } return redirect('/'); }
-
И, наконец, вы должны работать над методом
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');
Я думаю, что лучший способ сделать это - использовать промежуточные программы. Смотрите документ здесь
Вы можете легко создать промежуточное программное обеспечение, используя следующую команду 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
});
Вы можете создать промежуточное программное обеспечение под названием: PermissionFilter
В PermissionFilter вы проверяете, входит ли запрашивающий пользователь в группу или нет.
Сейчас я не могу предоставить демо-версию, но если вы хотите, я могу сделать демо-версию позже.
Промежуточное программное обеспечение L5: http://laravel.com/docs/5.1/middleware